'
else:
output = ""
- # We use ?character and ?time.time() to force the browser to reset caches
- img_bot = (
- f'

'
- if Path("user_data/cache/pfp_character_thumb.png").exists() else ''
- )
+ img_bot = get_character_image_with_cache_buster()
def create_message(role, content, raw_content):
"""Inner function for CAI-style messages."""
diff --git a/modules/presets.py b/modules/presets.py
index cf706605..3eb1f5fc 100644
--- a/modules/presets.py
+++ b/modules/presets.py
@@ -1,6 +1,5 @@
import functools
import pprint
-import random
from pathlib import Path
import yaml
@@ -93,68 +92,17 @@ def load_preset_for_ui(name, state):
return state, *[generate_params[k] for k in presets_params()]
-def random_preset(state):
- params_and_values = {
- 'remove_tail_tokens': {
- 'top_p': [0.5, 0.8, 0.9, 0.95, 0.99],
- 'min_p': [0.5, 0.2, 0.1, 0.05, 0.01],
- 'top_k': [3, 5, 10, 20, 30, 40],
- 'typical_p': [0.2, 0.575, 0.95],
- 'tfs': [0.5, 0.8, 0.9, 0.95, 0.99],
- 'top_a': [0.5, 0.2, 0.1, 0.05, 0.01],
- 'epsilon_cutoff': [1, 3, 5, 7, 9],
- 'eta_cutoff': [3, 6, 9, 12, 15, 18],
- },
- 'flatten_distribution': {
- 'temperature': [0.1, 0.5, 0.7, 0.8, 1, 1.2, 1.5, 2.0, 5.0],
- 'dynamic_temperature': [
- [0.1, 1],
- [0.1, 1.5],
- [0.1, 2],
- [0.1, 5],
- [0.5, 1],
- [0.5, 1.5],
- [0.5, 2],
- [0.5, 5],
- [0.8, 1],
- [0.8, 1.5],
- [0.8, 2],
- [0.8, 5],
- [1, 1.5],
- [1, 2],
- [1, 5]
- ],
- 'smoothing_factor': [0.2, 0.3, 0.6, 1.2],
- },
- 'repetition': {
- 'repetition_penalty': [1, 1.05, 1.1, 1.15, 1.20, 1.25],
- 'presence_penalty': [0, 0.1, 0.2, 0.4, 0.6, 0.8, 1.0, 2.0],
- 'frequency_penalty': [0, 0.1, 0.2, 0.4, 0.6, 0.8, 1.0, 2.0],
- },
- 'other': {
- 'temperature_last': [True, False],
- }
- }
-
- generate_params = default_preset()
- for cat in params_and_values:
- choices = list(params_and_values[cat].keys())
- if shared.args.loader is not None:
- choices = [x for x in choices if loader_contains(x)]
-
- if len(choices) > 0:
- choice = random.choice(choices)
- value = random.choice(params_and_values[cat][choice])
- if choice == 'dynamic_temperature':
- generate_params['dynamic_temperature'] = True
- generate_params['dynatemp_low'] = value[0]
- generate_params['dynatemp_high'] = value[1]
- else:
- generate_params[choice] = value
-
+def reset_preset_for_ui(name, state):
+ """Reset current preset to its saved values from file"""
+ generate_params = load_preset(name, verbose=True)
+ state.update(generate_params)
+ return state, *[generate_params[k] for k in presets_params()]
+
+
+def neutralize_samplers_for_ui(state):
+ """Set all samplers to their default/neutral values"""
+ generate_params = default_preset()
state.update(generate_params)
- logger.info("GENERATED_PRESET=")
- pprint.PrettyPrinter(indent=4, width=1, sort_dicts=False).pprint(remove_defaults(state))
return state, *[generate_params[k] for k in presets_params()]
diff --git a/modules/shared.py b/modules/shared.py
index 2e500779..f4f8e180 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -39,10 +39,6 @@ settings = {
'web_search_pages': 3,
'prompt-default': 'QA',
'prompt-notebook': 'QA',
- 'character': 'Assistant',
- 'name1': 'You',
- 'user_bio': '',
- 'custom_system_message': '',
'preset': 'min_p',
'max_new_tokens': 512,
'max_new_tokens_min': 1,
@@ -63,8 +59,64 @@ settings = {
'negative_prompt': '',
'dark_theme': True,
'default_extensions': [],
+
+ # Character settings
+ 'character': 'Assistant',
+ 'name1': 'You',
+ 'name2': 'AI',
+ 'user_bio': '',
+ 'context': 'The following is a conversation with an AI Large Language Model. The AI has been trained to answer questions, provide recommendations, and help with decision making. The AI follows user requests. The AI thinks outside the box.',
+ 'greeting': 'How can I help you today?',
+ 'custom_system_message': '',
'instruction_template_str': "{%- set ns = namespace(found=false) -%}\n{%- for message in messages -%}\n {%- if message['role'] == 'system' -%}\n {%- set ns.found = true -%}\n {%- endif -%}\n{%- endfor -%}\n{%- if not ns.found -%}\n {{- '' + 'Below is an instruction that describes a task. Write a response that appropriately completes the request.' + '\\n\\n' -}}\n{%- endif %}\n{%- for message in messages %}\n {%- if message['role'] == 'system' -%}\n {{- '' + message['content'] + '\\n\\n' -}}\n {%- else -%}\n {%- if message['role'] == 'user' -%}\n {{-'### Instruction:\\n' + message['content'] + '\\n\\n'-}}\n {%- else -%}\n {{-'### Response:\\n' + message['content'] + '\\n\\n' -}}\n {%- endif -%}\n {%- endif -%}\n{%- endfor -%}\n{%- if add_generation_prompt -%}\n {{-'### Response:\\n'-}}\n{%- endif -%}",
'chat_template_str': "{%- for message in messages %}\n {%- if message['role'] == 'system' -%}\n {%- if message['content'] -%}\n {{- message['content'] + '\\n\\n' -}}\n {%- endif -%}\n {%- if user_bio -%}\n {{- user_bio + '\\n\\n' -}}\n {%- endif -%}\n {%- else -%}\n {%- if message['role'] == 'user' -%}\n {{- name1 + ': ' + message['content'] + '\\n'-}}\n {%- else -%}\n {{- name2 + ': ' + message['content'] + '\\n' -}}\n {%- endif -%}\n {%- endif -%}\n{%- endfor -%}",
+
+ # Generation parameters - Curve shape
+ 'temperature': 1.0,
+ 'dynatemp_low': 1.0,
+ 'dynatemp_high': 1.0,
+ 'dynatemp_exponent': 1.0,
+ 'smoothing_factor': 0.0,
+ 'smoothing_curve': 1.0,
+
+ # Generation parameters - Curve cutoff
+ 'min_p': 0.0,
+ 'top_p': 1.0,
+ 'top_k': 0,
+ 'typical_p': 1.0,
+ 'xtc_threshold': 0.1,
+ 'xtc_probability': 0.0,
+ 'epsilon_cutoff': 0.0,
+ 'eta_cutoff': 0.0,
+ 'tfs': 1.0,
+ 'top_a': 0.0,
+ 'top_n_sigma': 0.0,
+
+ # Generation parameters - Repetition suppression
+ 'dry_multiplier': 0.0,
+ 'dry_allowed_length': 2,
+ 'dry_base': 1.75,
+ 'repetition_penalty': 1.0,
+ 'frequency_penalty': 0.0,
+ 'presence_penalty': 0.0,
+ 'encoder_repetition_penalty': 1.0,
+ 'no_repeat_ngram_size': 0,
+ 'repetition_penalty_range': 1024,
+
+ # Generation parameters - Alternative sampling methods
+ 'penalty_alpha': 0.0,
+ 'guidance_scale': 1.0,
+ 'mirostat_mode': 0,
+ 'mirostat_tau': 5.0,
+ 'mirostat_eta': 0.1,
+
+ # Generation parameters - Other options
+ 'do_sample': True,
+ 'dynamic_temperature': False,
+ 'temperature_last': False,
+ 'sampler_priority': 'repetition_penalty\npresence_penalty\nfrequency_penalty\ndry\ntop_n_sigma\ntemperature\ndynamic_temperature\nquadratic_sampling\ntop_k\ntop_p\ntypical_p\nepsilon_cutoff\neta_cutoff\ntfs\ntop_a\nmin_p\nmirostat\nxtc\nencoder_repetition_penalty\nno_repeat_ngram',
+ 'dry_sequence_breakers': '"\\n", ":", "\\"", "*"',
+ 'grammar_string': '',
}
default_settings = copy.deepcopy(settings)
@@ -75,7 +127,6 @@ parser = argparse.ArgumentParser(description="Text generation web UI", conflict_
# Basic settings
group = parser.add_argument_group('Basic settings')
group.add_argument('--multi-user', action='store_true', help='Multi-user mode. Chat histories are not saved or automatically loaded. Warning: this is likely not safe for sharing publicly.')
-group.add_argument('--character', type=str, help='The name of the character to load in chat mode by default.')
group.add_argument('--model', type=str, help='Name of the model to load by default.')
group.add_argument('--lora', type=str, nargs='+', help='The list of LoRAs to load. If you want to load more than one LoRA, write the names separated by spaces.')
group.add_argument('--model-dir', type=str, default='user_data/models', help='Path to directory with all the models.')
diff --git a/modules/ui.py b/modules/ui.py
index db3adf0f..8ec4b165 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -310,7 +310,7 @@ def apply_interface_values(state, use_persistent=False):
def save_settings(state, preset, extensions_list, show_controls, theme_state):
output = copy.deepcopy(shared.settings)
- exclude = ['name2', 'greeting', 'context', 'truncation_length', 'instruction_template_str']
+ exclude = []
for k in state:
if k in shared.settings and k not in exclude:
output[k] = state[k]
@@ -323,6 +323,7 @@ def save_settings(state, preset, extensions_list, show_controls, theme_state):
output['seed'] = int(output['seed'])
output['show_controls'] = show_controls
output['dark_theme'] = True if theme_state == 'dark' else False
+ output.pop('instruction_template_str')
# Save extension values in the UI
for extension_name in extensions_list:
@@ -364,7 +365,7 @@ def store_current_state_and_debounce(interface_state, preset, extensions, show_c
if _auto_save_timer is not None:
_auto_save_timer.cancel()
- _auto_save_timer = threading.Timer(2.0, _perform_debounced_save)
+ _auto_save_timer = threading.Timer(1.0, _perform_debounced_save)
_auto_save_timer.start()
@@ -401,15 +402,52 @@ def setup_auto_save():
'chat-instruct_command',
'character_menu',
'name1',
+ 'name2',
+ 'context',
+ 'greeting',
'user_bio',
'custom_system_message',
'chat_template_str',
- # Parameters tab (ui_parameters.py)
+ # Parameters tab (ui_parameters.py) - Generation parameters
'preset_menu',
+ 'temperature',
+ 'dynatemp_low',
+ 'dynatemp_high',
+ 'dynatemp_exponent',
+ 'smoothing_factor',
+ 'smoothing_curve',
+ 'min_p',
+ 'top_p',
+ 'top_k',
+ 'typical_p',
+ 'xtc_threshold',
+ 'xtc_probability',
+ 'epsilon_cutoff',
+ 'eta_cutoff',
+ 'tfs',
+ 'top_a',
+ 'top_n_sigma',
+ 'dry_multiplier',
+ 'dry_allowed_length',
+ 'dry_base',
+ 'repetition_penalty',
+ 'frequency_penalty',
+ 'presence_penalty',
+ 'encoder_repetition_penalty',
+ 'no_repeat_ngram_size',
+ 'repetition_penalty_range',
+ 'penalty_alpha',
+ 'guidance_scale',
+ 'mirostat_mode',
+ 'mirostat_tau',
+ 'mirostat_eta',
'max_new_tokens',
'prompt_lookup_num_tokens',
'max_tokens_second',
+ 'do_sample',
+ 'dynamic_temperature',
+ 'temperature_last',
'auto_max_new_tokens',
'ban_eos_token',
'add_bos_token',
@@ -417,10 +455,14 @@ def setup_auto_save():
'skip_special_tokens',
'stream',
'static_cache',
+ 'truncation_length',
'seed',
+ 'sampler_priority',
'custom_stopping_strings',
'custom_token_bans',
'negative_prompt',
+ 'dry_sequence_breakers',
+ 'grammar_string',
# Default tab (ui_default.py)
'prompt_menu-default',
diff --git a/modules/ui_chat.py b/modules/ui_chat.py
index 0d5a2c18..712843d3 100644
--- a/modules/ui_chat.py
+++ b/modules/ui_chat.py
@@ -86,7 +86,7 @@ def create_ui():
shared.gradio['web_search_pages'] = gr.Number(value=shared.settings.get('web_search_pages', 3), precision=0, label='Number of pages to download', minimum=1, maximum=10)
with gr.Row():
- shared.gradio['mode'] = gr.Radio(choices=['instruct', 'chat-instruct', 'chat'], value=shared.settings['mode'] if shared.settings['mode'] in ['chat', 'chat-instruct'] else None, label='Mode', info='Defines how the chat prompt is generated. In instruct and chat-instruct modes, the instruction template Parameters > Instruction template is used.', elem_id='chat-mode')
+ shared.gradio['mode'] = gr.Radio(choices=['instruct', 'chat-instruct', 'chat'], value=None, label='Mode', info='Defines how the chat prompt is generated. In instruct and chat-instruct modes, the instruction template Parameters > Instruction template is used.', elem_id='chat-mode')
with gr.Row():
shared.gradio['chat_style'] = gr.Dropdown(choices=utils.get_available_chat_styles(), label='Chat style', value=shared.settings['chat_style'], visible=shared.settings['mode'] != 'instruct')
@@ -118,14 +118,16 @@ def create_chat_settings_ui():
with gr.Column(scale=8):
with gr.Tab("Character"):
with gr.Row():
- shared.gradio['character_menu'] = gr.Dropdown(value=None, choices=utils.get_available_characters(), label='Character', elem_id='character-menu', info='Used in chat and chat-instruct modes.', elem_classes='slim-dropdown')
+ shared.gradio['character_menu'] = gr.Dropdown(value=shared.settings['character'], choices=utils.get_available_characters(), label='Character', elem_id='character-menu', info='Used in chat and chat-instruct modes.', elem_classes='slim-dropdown')
ui.create_refresh_button(shared.gradio['character_menu'], lambda: None, lambda: {'choices': utils.get_available_characters()}, 'refresh-button', interactive=not mu)
shared.gradio['save_character'] = gr.Button('💾', elem_classes='refresh-button', elem_id="save-character", interactive=not mu)
shared.gradio['delete_character'] = gr.Button('🗑️', elem_classes='refresh-button', interactive=not mu)
+ shared.gradio['reset_character'] = gr.Button('↺', elem_classes='refresh-button', interactive=True)
+ shared.gradio['clear_character'] = gr.Button('⚪', elem_classes='refresh-button', interactive=True)
- shared.gradio['name2'] = gr.Textbox(value='', lines=1, label='Character\'s name')
- shared.gradio['context'] = gr.Textbox(value='', lines=10, label='Context', elem_classes=['add_scrollbar'])
- shared.gradio['greeting'] = gr.Textbox(value='', lines=5, label='Greeting', elem_classes=['add_scrollbar'])
+ shared.gradio['name2'] = gr.Textbox(value=shared.settings['name2'], lines=1, label='Character\'s name')
+ shared.gradio['context'] = gr.Textbox(value=shared.settings['context'], lines=10, label='Context', elem_classes=['add_scrollbar'])
+ shared.gradio['greeting'] = gr.Textbox(value=shared.settings['greeting'], lines=5, label='Greeting', elem_classes=['add_scrollbar'])
with gr.Tab("User"):
shared.gradio['name1'] = gr.Textbox(value=shared.settings['name1'], lines=1, label='Name')
@@ -178,7 +180,7 @@ def create_chat_settings_ui():
with gr.Row():
with gr.Column():
shared.gradio['custom_system_message'] = gr.Textbox(value=shared.settings['custom_system_message'], lines=2, label='Custom system message', info='If not empty, will be used instead of the default one.', elem_classes=['add_scrollbar'])
- shared.gradio['instruction_template_str'] = gr.Textbox(value='', label='Instruction template', lines=24, info='This gets autodetected; you usually don\'t need to change it. Used in instruct and chat-instruct modes.', elem_classes=['add_scrollbar', 'monospace'])
+ shared.gradio['instruction_template_str'] = gr.Textbox(value=shared.settings['instruction_template_str'], label='Instruction template', lines=24, info='This gets autodetected; you usually don\'t need to change it. Used in instruct and chat-instruct modes.', elem_classes=['add_scrollbar', 'monospace'])
with gr.Row():
shared.gradio['send_instruction_to_default'] = gr.Button('Send to default', elem_classes=['small-button'])
shared.gradio['send_instruction_to_notebook'] = gr.Button('Send to notebook', elem_classes=['small-button'])
@@ -294,6 +296,8 @@ def create_event_handlers():
chat.handle_character_menu_change, gradio('interface_state'), gradio('history', 'display', 'name1', 'name2', 'character_picture', 'greeting', 'context', 'unique_id'), show_progress=False).then(
None, None, None, js=f'() => {{{ui.update_big_picture_js}; updateBigPicture()}}')
+ shared.gradio['character_picture'].change(chat.handle_character_picture_change, gradio('character_picture'), None, show_progress=False)
+
shared.gradio['mode'].change(
ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
chat.handle_mode_change, gradio('interface_state'), gradio('history', 'display', 'chat_style', 'chat-instruct_command', 'unique_id'), show_progress=False).then(
@@ -317,6 +321,10 @@ def create_event_handlers():
ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
chat.handle_save_template_click, gradio('instruction_template_str'), gradio('save_filename', 'save_root', 'save_contents', 'file_saver'), show_progress=False)
+ shared.gradio['reset_character'].click(
+ ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
+ chat.reset_character_for_ui, gradio('interface_state'), gradio('interface_state', 'name2', 'context', 'greeting', 'character_picture'), show_progress=False)
+
shared.gradio['delete_template'].click(chat.handle_delete_template_click, gradio('instruction_template'), gradio('delete_filename', 'delete_root', 'file_deleter'), show_progress=False)
shared.gradio['save_chat_history'].click(
lambda x: json.dumps(x, indent=4), gradio('history'), gradio('temporary_text')).then(
diff --git a/modules/ui_default.py b/modules/ui_default.py
index c2946b37..8acc4b10 100644
--- a/modules/ui_default.py
+++ b/modules/ui_default.py
@@ -19,7 +19,7 @@ def create_ui():
with gr.Row():
with gr.Column():
with gr.Row():
- shared.gradio['textbox-default'] = gr.Textbox(value='', lines=27, label='Input', elem_classes=['textbox_default', 'add_scrollbar'])
+ shared.gradio['textbox-default'] = gr.Textbox(value=load_prompt(shared.settings['prompt-default']), lines=27, label='Input', elem_classes=['textbox_default', 'add_scrollbar'])
shared.gradio['token-counter-default'] = gr.HTML(value="
0", elem_id="default-token-counter")
with gr.Row():
@@ -28,7 +28,7 @@ def create_ui():
shared.gradio['Generate-default'] = gr.Button('Generate', variant='primary')
with gr.Row():
- shared.gradio['prompt_menu-default'] = gr.Dropdown(choices=utils.get_available_prompts(), value='None', label='Prompt', elem_classes='slim-dropdown')
+ shared.gradio['prompt_menu-default'] = gr.Dropdown(choices=utils.get_available_prompts(), value=shared.settings['prompt-default'], label='Prompt', elem_classes='slim-dropdown')
ui.create_refresh_button(shared.gradio['prompt_menu-default'], lambda: None, lambda: {'choices': utils.get_available_prompts()}, 'refresh-button', interactive=not mu)
shared.gradio['save_prompt-default'] = gr.Button('💾', elem_classes='refresh-button', interactive=not mu)
shared.gradio['delete_prompt-default'] = gr.Button('🗑️', elem_classes='refresh-button', interactive=not mu)
diff --git a/modules/ui_notebook.py b/modules/ui_notebook.py
index b234ac57..3f79a93c 100644
--- a/modules/ui_notebook.py
+++ b/modules/ui_notebook.py
@@ -22,7 +22,7 @@ def create_ui():
with gr.Column(scale=4):
with gr.Tab('Raw'):
with gr.Row():
- shared.gradio['textbox-notebook'] = gr.Textbox(value='', lines=27, elem_id='textbox-notebook', elem_classes=['textbox', 'add_scrollbar'])
+ shared.gradio['textbox-notebook'] = gr.Textbox(value=load_prompt(shared.settings['prompt-notebook']), lines=27, elem_id='textbox-notebook', elem_classes=['textbox', 'add_scrollbar'])
shared.gradio['token-counter-notebook'] = gr.HTML(value="
0", elem_id="notebook-token-counter")
with gr.Tab('Markdown'):
@@ -56,7 +56,7 @@ def create_ui():
with gr.Column(scale=1):
gr.HTML('
')
with gr.Row():
- shared.gradio['prompt_menu-notebook'] = gr.Dropdown(choices=utils.get_available_prompts(), value='None', label='Prompt', elem_classes='slim-dropdown')
+ shared.gradio['prompt_menu-notebook'] = gr.Dropdown(choices=utils.get_available_prompts(), value=shared.settings['prompt-notebook'], label='Prompt', elem_classes='slim-dropdown')
ui.create_refresh_button(shared.gradio['prompt_menu-notebook'], lambda: None, lambda: {'choices': utils.get_available_prompts()}, ['refresh-button', 'refresh-button-small'], interactive=not mu)
shared.gradio['save_prompt-notebook'] = gr.Button('💾', elem_classes=['refresh-button', 'refresh-button-small'], interactive=not mu)
shared.gradio['delete_prompt-notebook'] = gr.Button('🗑️', elem_classes=['refresh-button', 'refresh-button-small'], interactive=not mu)
diff --git a/modules/ui_parameters.py b/modules/ui_parameters.py
index 84f9fbfc..ff965d39 100644
--- a/modules/ui_parameters.py
+++ b/modules/ui_parameters.py
@@ -6,19 +6,19 @@ from modules import loaders, presets, shared, ui, ui_chat, utils
from modules.utils import gradio
-def create_ui(default_preset):
+def create_ui():
mu = shared.args.multi_user
- generate_params = presets.load_preset(default_preset)
with gr.Tab("Parameters", elem_id="parameters"):
with gr.Tab("Generation"):
with gr.Row():
with gr.Column():
with gr.Row():
- shared.gradio['preset_menu'] = gr.Dropdown(choices=utils.get_available_presets(), value=default_preset, label='Preset', elem_classes='slim-dropdown')
+ shared.gradio['preset_menu'] = gr.Dropdown(choices=utils.get_available_presets(), value=shared.settings['preset'], label='Preset', elem_classes='slim-dropdown')
ui.create_refresh_button(shared.gradio['preset_menu'], lambda: None, lambda: {'choices': utils.get_available_presets()}, 'refresh-button', interactive=not mu)
shared.gradio['save_preset'] = gr.Button('💾', elem_classes='refresh-button', interactive=not mu)
shared.gradio['delete_preset'] = gr.Button('🗑️', elem_classes='refresh-button', interactive=not mu)
- shared.gradio['random_preset'] = gr.Button('🎲', elem_classes='refresh-button')
+ shared.gradio['reset_preset'] = gr.Button('Reload preset', elem_classes='refresh-button', interactive=True)
+ shared.gradio['neutralize_samplers'] = gr.Button('Neutralize samplers', elem_classes='refresh-button', interactive=True)
with gr.Column():
shared.gradio['filter_by_loader'] = gr.Dropdown(label="Filter by loader", choices=["All"] + list(loaders.loaders_and_params.keys()) if not shared.args.portable else ['llama.cpp'], value="All", elem_classes='slim-dropdown')
@@ -28,44 +28,44 @@ def create_ui(default_preset):
with gr.Row():
with gr.Column():
gr.Markdown('## Curve shape')
- shared.gradio['temperature'] = gr.Slider(0.01, 5, value=generate_params['temperature'], step=0.01, label='temperature')
- shared.gradio['dynatemp_low'] = gr.Slider(0.01, 5, value=generate_params['dynatemp_low'], step=0.01, label='dynatemp_low', visible=generate_params['dynamic_temperature'])
- shared.gradio['dynatemp_high'] = gr.Slider(0.01, 5, value=generate_params['dynatemp_high'], step=0.01, label='dynatemp_high', visible=generate_params['dynamic_temperature'])
- shared.gradio['dynatemp_exponent'] = gr.Slider(0.01, 5, value=generate_params['dynatemp_exponent'], step=0.01, label='dynatemp_exponent', visible=generate_params['dynamic_temperature'])
- shared.gradio['smoothing_factor'] = gr.Slider(0.0, 10.0, value=generate_params['smoothing_factor'], step=0.01, label='smoothing_factor', info='Activates Quadratic Sampling.')
- shared.gradio['smoothing_curve'] = gr.Slider(1.0, 10.0, value=generate_params['smoothing_curve'], step=0.01, label='smoothing_curve', info='Adjusts the dropoff curve of Quadratic Sampling.')
+ shared.gradio['temperature'] = gr.Slider(0.01, 5, value=shared.settings['temperature'], step=0.01, label='temperature')
+ shared.gradio['dynatemp_low'] = gr.Slider(0.01, 5, value=shared.settings['dynatemp_low'], step=0.01, label='dynatemp_low', visible=shared.settings['dynamic_temperature'])
+ shared.gradio['dynatemp_high'] = gr.Slider(0.01, 5, value=shared.settings['dynatemp_high'], step=0.01, label='dynatemp_high', visible=shared.settings['dynamic_temperature'])
+ shared.gradio['dynatemp_exponent'] = gr.Slider(0.01, 5, value=shared.settings['dynatemp_exponent'], step=0.01, label='dynatemp_exponent', visible=shared.settings['dynamic_temperature'])
+ shared.gradio['smoothing_factor'] = gr.Slider(0.0, 10.0, value=shared.settings['smoothing_factor'], step=0.01, label='smoothing_factor', info='Activates Quadratic Sampling.')
+ shared.gradio['smoothing_curve'] = gr.Slider(1.0, 10.0, value=shared.settings['smoothing_curve'], step=0.01, label='smoothing_curve', info='Adjusts the dropoff curve of Quadratic Sampling.')
gr.Markdown('## Curve cutoff')
- shared.gradio['min_p'] = gr.Slider(0.0, 1.0, value=generate_params['min_p'], step=0.01, label='min_p')
- shared.gradio['top_n_sigma'] = gr.Slider(0.0, 5.0, value=generate_params['top_n_sigma'], step=0.01, label='top_n_sigma')
- shared.gradio['top_p'] = gr.Slider(0.0, 1.0, value=generate_params['top_p'], step=0.01, label='top_p')
- shared.gradio['top_k'] = gr.Slider(0, 200, value=generate_params['top_k'], step=1, label='top_k')
- shared.gradio['typical_p'] = gr.Slider(0.0, 1.0, value=generate_params['typical_p'], step=0.01, label='typical_p')
- shared.gradio['xtc_threshold'] = gr.Slider(0, 0.5, value=generate_params['xtc_threshold'], step=0.01, label='xtc_threshold', info='If 2 or more tokens have probability above this threshold, consider removing all but the last one.')
- shared.gradio['xtc_probability'] = gr.Slider(0, 1, value=generate_params['xtc_probability'], step=0.01, label='xtc_probability', info='Probability that the removal will actually happen. 0 disables the sampler. 1 makes it always happen.')
- shared.gradio['epsilon_cutoff'] = gr.Slider(0, 9, value=generate_params['epsilon_cutoff'], step=0.01, label='epsilon_cutoff')
- shared.gradio['eta_cutoff'] = gr.Slider(0, 20, value=generate_params['eta_cutoff'], step=0.01, label='eta_cutoff')
- 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['min_p'] = gr.Slider(0.0, 1.0, value=shared.settings['min_p'], step=0.01, label='min_p')
+ shared.gradio['top_n_sigma'] = gr.Slider(0.0, 5.0, value=shared.settings['top_n_sigma'], step=0.01, label='top_n_sigma')
+ shared.gradio['top_p'] = gr.Slider(0.0, 1.0, value=shared.settings['top_p'], step=0.01, label='top_p')
+ shared.gradio['top_k'] = gr.Slider(0, 200, value=shared.settings['top_k'], step=1, label='top_k')
+ shared.gradio['typical_p'] = gr.Slider(0.0, 1.0, value=shared.settings['typical_p'], step=0.01, label='typical_p')
+ shared.gradio['xtc_threshold'] = gr.Slider(0, 0.5, value=shared.settings['xtc_threshold'], step=0.01, label='xtc_threshold', info='If 2 or more tokens have probability above this threshold, consider removing all but the last one.')
+ shared.gradio['xtc_probability'] = gr.Slider(0, 1, value=shared.settings['xtc_probability'], step=0.01, label='xtc_probability', info='Probability that the removal will actually happen. 0 disables the sampler. 1 makes it always happen.')
+ shared.gradio['epsilon_cutoff'] = gr.Slider(0, 9, value=shared.settings['epsilon_cutoff'], step=0.01, label='epsilon_cutoff')
+ shared.gradio['eta_cutoff'] = gr.Slider(0, 20, value=shared.settings['eta_cutoff'], step=0.01, label='eta_cutoff')
+ shared.gradio['tfs'] = gr.Slider(0.0, 1.0, value=shared.settings['tfs'], step=0.01, label='tfs')
+ shared.gradio['top_a'] = gr.Slider(0.0, 1.0, value=shared.settings['top_a'], step=0.01, label='top_a')
gr.Markdown('## Repetition suppression')
- shared.gradio['dry_multiplier'] = gr.Slider(0, 5, value=generate_params['dry_multiplier'], step=0.01, label='dry_multiplier', info='Set to greater than 0 to enable DRY. Recommended value: 0.8.')
- shared.gradio['dry_allowed_length'] = gr.Slider(1, 20, value=generate_params['dry_allowed_length'], step=1, label='dry_allowed_length', info='Longest sequence that can be repeated without being penalized.')
- shared.gradio['dry_base'] = gr.Slider(1, 4, value=generate_params['dry_base'], step=0.01, label='dry_base', info='Controls how fast the penalty grows with increasing sequence length.')
- shared.gradio['repetition_penalty'] = gr.Slider(1.0, 1.5, value=generate_params['repetition_penalty'], step=0.01, label='repetition_penalty')
- shared.gradio['frequency_penalty'] = gr.Slider(0, 2, value=generate_params['frequency_penalty'], step=0.05, label='frequency_penalty')
- shared.gradio['presence_penalty'] = gr.Slider(0, 2, value=generate_params['presence_penalty'], step=0.05, label='presence_penalty')
- shared.gradio['encoder_repetition_penalty'] = gr.Slider(0.8, 1.5, value=generate_params['encoder_repetition_penalty'], step=0.01, label='encoder_repetition_penalty')
- shared.gradio['no_repeat_ngram_size'] = gr.Slider(0, 20, step=1, value=generate_params['no_repeat_ngram_size'], label='no_repeat_ngram_size')
- shared.gradio['repetition_penalty_range'] = gr.Slider(0, 4096, step=64, value=generate_params['repetition_penalty_range'], label='repetition_penalty_range')
+ shared.gradio['dry_multiplier'] = gr.Slider(0, 5, value=shared.settings['dry_multiplier'], step=0.01, label='dry_multiplier', info='Set to greater than 0 to enable DRY. Recommended value: 0.8.')
+ shared.gradio['dry_allowed_length'] = gr.Slider(1, 20, value=shared.settings['dry_allowed_length'], step=1, label='dry_allowed_length', info='Longest sequence that can be repeated without being penalized.')
+ shared.gradio['dry_base'] = gr.Slider(1, 4, value=shared.settings['dry_base'], step=0.01, label='dry_base', info='Controls how fast the penalty grows with increasing sequence length.')
+ shared.gradio['repetition_penalty'] = gr.Slider(1.0, 1.5, value=shared.settings['repetition_penalty'], step=0.01, label='repetition_penalty')
+ shared.gradio['frequency_penalty'] = gr.Slider(0, 2, value=shared.settings['frequency_penalty'], step=0.05, label='frequency_penalty')
+ shared.gradio['presence_penalty'] = gr.Slider(0, 2, value=shared.settings['presence_penalty'], step=0.05, label='presence_penalty')
+ shared.gradio['encoder_repetition_penalty'] = gr.Slider(0.8, 1.5, value=shared.settings['encoder_repetition_penalty'], step=0.01, label='encoder_repetition_penalty')
+ shared.gradio['no_repeat_ngram_size'] = gr.Slider(0, 20, step=1, value=shared.settings['no_repeat_ngram_size'], label='no_repeat_ngram_size')
+ shared.gradio['repetition_penalty_range'] = gr.Slider(0, 4096, step=64, value=shared.settings['repetition_penalty_range'], label='repetition_penalty_range')
with gr.Column():
gr.Markdown('## Alternative sampling methods')
- shared.gradio['penalty_alpha'] = gr.Slider(0, 5, value=generate_params['penalty_alpha'], label='penalty_alpha', info='For Contrastive Search. do_sample must be unchecked.')
- shared.gradio['guidance_scale'] = gr.Slider(-0.5, 2.5, step=0.05, value=generate_params['guidance_scale'], label='guidance_scale', info='For CFG. 1.5 is a good value.')
- shared.gradio['mirostat_mode'] = gr.Slider(0, 2, step=1, value=generate_params['mirostat_mode'], label='mirostat_mode', info='mode=1 is for llama.cpp only.')
- shared.gradio['mirostat_tau'] = gr.Slider(0, 10, step=0.01, value=generate_params['mirostat_tau'], label='mirostat_tau')
- shared.gradio['mirostat_eta'] = gr.Slider(0, 1, step=0.01, value=generate_params['mirostat_eta'], label='mirostat_eta')
+ shared.gradio['penalty_alpha'] = gr.Slider(0, 5, value=shared.settings['penalty_alpha'], label='penalty_alpha', info='For Contrastive Search. do_sample must be unchecked.')
+ shared.gradio['guidance_scale'] = gr.Slider(-0.5, 2.5, step=0.05, value=shared.settings['guidance_scale'], label='guidance_scale', info='For CFG. 1.5 is a good value.')
+ shared.gradio['mirostat_mode'] = gr.Slider(0, 2, step=1, value=shared.settings['mirostat_mode'], label='mirostat_mode', info='mode=1 is for llama.cpp only.')
+ shared.gradio['mirostat_tau'] = gr.Slider(0, 10, step=0.01, value=shared.settings['mirostat_tau'], label='mirostat_tau')
+ shared.gradio['mirostat_eta'] = gr.Slider(0, 1, step=0.01, value=shared.settings['mirostat_eta'], label='mirostat_eta')
gr.Markdown('## Other options')
shared.gradio['max_new_tokens'] = gr.Slider(minimum=shared.settings['max_new_tokens_min'], maximum=shared.settings['max_new_tokens_max'], value=shared.settings['max_new_tokens'], step=1, label='max_new_tokens', info='⚠️ Setting this too high can cause prompt truncation.')
@@ -74,9 +74,9 @@ def create_ui(default_preset):
with gr.Column():
with gr.Row():
with gr.Column():
- shared.gradio['do_sample'] = gr.Checkbox(value=generate_params['do_sample'], label='do_sample')
- shared.gradio['dynamic_temperature'] = gr.Checkbox(value=generate_params['dynamic_temperature'], label='dynamic_temperature')
- shared.gradio['temperature_last'] = gr.Checkbox(value=generate_params['temperature_last'], label='temperature_last', info='Moves temperature/dynamic temperature/quadratic sampling to the end of the sampler stack, ignoring their positions in "Sampler priority".')
+ shared.gradio['do_sample'] = gr.Checkbox(value=shared.settings['do_sample'], label='do_sample')
+ shared.gradio['dynamic_temperature'] = gr.Checkbox(value=shared.settings['dynamic_temperature'], label='dynamic_temperature')
+ shared.gradio['temperature_last'] = gr.Checkbox(value=shared.settings['temperature_last'], label='temperature_last', info='Moves temperature/dynamic temperature/quadratic sampling to the end of the sampler stack, ignoring their positions in "Sampler priority".')
shared.gradio['auto_max_new_tokens'] = gr.Checkbox(value=shared.settings['auto_max_new_tokens'], label='auto_max_new_tokens', info='Expand max_new_tokens to the available context length.')
shared.gradio['ban_eos_token'] = gr.Checkbox(value=shared.settings['ban_eos_token'], label='Ban the eos_token', info='Forces the model to never end the generation prematurely.')
shared.gradio['add_bos_token'] = gr.Checkbox(value=shared.settings['add_bos_token'], label='Add the bos_token to the beginning of prompts', info='Disabling this can make the replies more creative.')
@@ -89,18 +89,18 @@ def create_ui(default_preset):
shared.gradio['truncation_length'] = gr.Number(precision=0, step=256, value=get_truncation_length(), label='Truncate the prompt up to this length', info='The leftmost tokens are removed if the prompt exceeds this length.')
shared.gradio['seed'] = gr.Number(value=shared.settings['seed'], label='Seed (-1 for random)')
- shared.gradio['sampler_priority'] = gr.Textbox(value=generate_params['sampler_priority'], lines=12, label='Sampler priority', info='Parameter names separated by new lines or commas.', elem_classes=['add_scrollbar'])
+ shared.gradio['sampler_priority'] = gr.Textbox(value=shared.settings['sampler_priority'], lines=12, label='Sampler priority', info='Parameter names separated by new lines or commas.', elem_classes=['add_scrollbar'])
shared.gradio['custom_stopping_strings'] = gr.Textbox(lines=2, value=shared.settings["custom_stopping_strings"] or None, label='Custom stopping strings', info='Written between "" and separated by commas.', placeholder='"\\n", "\\nYou:"')
shared.gradio['custom_token_bans'] = gr.Textbox(value=shared.settings['custom_token_bans'] or None, label='Token bans', info='Token IDs to ban, separated by commas. The IDs can be found in the Default or Notebook tab.')
shared.gradio['negative_prompt'] = gr.Textbox(value=shared.settings['negative_prompt'], label='Negative prompt', info='For CFG. Only used when guidance_scale is different than 1.', lines=3, elem_classes=['add_scrollbar'])
- shared.gradio['dry_sequence_breakers'] = gr.Textbox(value=generate_params['dry_sequence_breakers'], label='dry_sequence_breakers', info='Tokens across which sequence matching is not continued. Specified as a comma-separated list of quoted strings.')
+ shared.gradio['dry_sequence_breakers'] = gr.Textbox(value=shared.settings['dry_sequence_breakers'], label='dry_sequence_breakers', info='Tokens across which sequence matching is not continued. Specified as a comma-separated list of quoted strings.')
with gr.Row() as shared.gradio['grammar_file_row']:
shared.gradio['grammar_file'] = gr.Dropdown(value='None', choices=utils.get_available_grammars(), label='Load grammar from file (.gbnf)', elem_classes='slim-dropdown')
ui.create_refresh_button(shared.gradio['grammar_file'], lambda: None, lambda: {'choices': utils.get_available_grammars()}, 'refresh-button', interactive=not mu)
shared.gradio['save_grammar'] = gr.Button('💾', elem_classes='refresh-button', interactive=not mu)
shared.gradio['delete_grammar'] = gr.Button('🗑️ ', elem_classes='refresh-button', interactive=not mu)
- shared.gradio['grammar_string'] = gr.Textbox(value='', label='Grammar', lines=16, elem_classes=['add_scrollbar', 'monospace'])
+ shared.gradio['grammar_string'] = gr.Textbox(value=shared.settings['grammar_string'], label='Grammar', lines=16, elem_classes=['add_scrollbar', 'monospace'])
ui_chat.create_chat_settings_ui()
@@ -111,9 +111,13 @@ def create_event_handlers():
ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
presets.load_preset_for_ui, gradio('preset_menu', 'interface_state'), gradio('interface_state') + gradio(presets.presets_params()), show_progress=False)
- shared.gradio['random_preset'].click(
+ shared.gradio['reset_preset'].click(
ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
- presets.random_preset, gradio('interface_state'), gradio('interface_state') + gradio(presets.presets_params()), show_progress=False)
+ presets.reset_preset_for_ui, gradio('preset_menu', 'interface_state'), gradio('interface_state') + gradio(presets.presets_params()), show_progress=False)
+
+ shared.gradio['neutralize_samplers'].click(
+ ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
+ presets.neutralize_samplers_for_ui, gradio('interface_state'), gradio('interface_state') + gradio(presets.presets_params()), show_progress=False)
shared.gradio['grammar_file'].change(load_grammar, gradio('grammar_file'), gradio('grammar_string'), show_progress=False)
shared.gradio['dynamic_temperature'].change(lambda x: [gr.update(visible=x)] * 3, gradio('dynamic_temperature'), gradio('dynatemp_low', 'dynatemp_high', 'dynatemp_exponent'), show_progress=False)
diff --git a/server.py b/server.py
index 3be4c27c..3dd0a3f3 100644
--- a/server.py
+++ b/server.py
@@ -45,6 +45,7 @@ from modules import (
ui_session,
utils
)
+from modules.chat import generate_pfp_cache
from modules.extensions import apply_extensions
from modules.LoRA import add_lora_to_model
from modules.models import load_model, unload_model_if_idle
@@ -93,17 +94,20 @@ def create_interface():
# Force some events to be triggered on page load
shared.persistent_interface_state.update({
+ 'mode': shared.settings['mode'],
'loader': shared.args.loader or 'llama.cpp',
- 'mode': shared.settings['mode'] if shared.settings['mode'] == 'instruct' else gr.update(),
- 'character_menu': shared.args.character or shared.settings['character'],
- 'instruction_template_str': shared.settings['instruction_template_str'],
- 'prompt_menu-default': shared.settings['prompt-default'],
- 'prompt_menu-notebook': shared.settings['prompt-notebook'],
'filter_by_loader': (shared.args.loader or 'All') if not shared.args.portable else 'llama.cpp'
})
- if Path("user_data/cache/pfp_character.png").exists():
- Path("user_data/cache/pfp_character.png").unlink()
+ # Clear existing cache files
+ for cache_file in ['pfp_character.png', 'pfp_character_thumb.png']:
+ cache_path = Path(f"user_data/cache/{cache_file}")
+ if cache_path.exists():
+ cache_path.unlink()
+
+ # Regenerate for default character
+ if shared.settings['mode'] != 'instruct':
+ generate_pfp_cache(shared.settings['character'])
# css/js strings
css = ui.css
@@ -134,7 +138,7 @@ def create_interface():
ui_default.create_ui()
ui_notebook.create_ui()
- ui_parameters.create_ui(shared.settings['preset']) # Parameters tab
+ ui_parameters.create_ui() # Parameters tab
ui_model_menu.create_ui() # Model tab
if not shared.args.portable:
training.create_ui() # Training tab
From 3650a6fd1fc332f462bc1aa08f7671a3d517d847 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sat, 7 Jun 2025 22:02:34 -0700
Subject: [PATCH 37/82] Small UI changes
---
css/main.css | 2 +-
modules/ui_chat.py | 3 +--
modules/ui_parameters.py | 2 +-
3 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/css/main.css b/css/main.css
index a9cb36ab..4277519a 100644
--- a/css/main.css
+++ b/css/main.css
@@ -53,7 +53,7 @@ div.svelte-iyf88w {
}
.refresh-button {
- max-width: 4.4em;
+ max-width: none;
min-width: 2.2em !important;
height: 39.594px;
align-self: end;
diff --git a/modules/ui_chat.py b/modules/ui_chat.py
index 712843d3..f8e2fc32 100644
--- a/modules/ui_chat.py
+++ b/modules/ui_chat.py
@@ -122,8 +122,7 @@ def create_chat_settings_ui():
ui.create_refresh_button(shared.gradio['character_menu'], lambda: None, lambda: {'choices': utils.get_available_characters()}, 'refresh-button', interactive=not mu)
shared.gradio['save_character'] = gr.Button('💾', elem_classes='refresh-button', elem_id="save-character", interactive=not mu)
shared.gradio['delete_character'] = gr.Button('🗑️', elem_classes='refresh-button', interactive=not mu)
- shared.gradio['reset_character'] = gr.Button('↺', elem_classes='refresh-button', interactive=True)
- shared.gradio['clear_character'] = gr.Button('⚪', elem_classes='refresh-button', interactive=True)
+ shared.gradio['reset_character'] = gr.Button('Restore character', elem_classes='refresh-button', interactive=True)
shared.gradio['name2'] = gr.Textbox(value=shared.settings['name2'], lines=1, label='Character\'s name')
shared.gradio['context'] = gr.Textbox(value=shared.settings['context'], lines=10, label='Context', elem_classes=['add_scrollbar'])
diff --git a/modules/ui_parameters.py b/modules/ui_parameters.py
index ff965d39..9b5cb3ab 100644
--- a/modules/ui_parameters.py
+++ b/modules/ui_parameters.py
@@ -17,7 +17,7 @@ def create_ui():
ui.create_refresh_button(shared.gradio['preset_menu'], lambda: None, lambda: {'choices': utils.get_available_presets()}, 'refresh-button', interactive=not mu)
shared.gradio['save_preset'] = gr.Button('💾', elem_classes='refresh-button', interactive=not mu)
shared.gradio['delete_preset'] = gr.Button('🗑️', elem_classes='refresh-button', interactive=not mu)
- shared.gradio['reset_preset'] = gr.Button('Reload preset', elem_classes='refresh-button', interactive=True)
+ shared.gradio['reset_preset'] = gr.Button('Restore preset', elem_classes='refresh-button', interactive=True)
shared.gradio['neutralize_samplers'] = gr.Button('Neutralize samplers', elem_classes='refresh-button', interactive=True)
with gr.Column():
From caf9fca5f339e4018913608f8accb3897352853f Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sat, 7 Jun 2025 22:11:35 -0700
Subject: [PATCH 38/82] Avoid some code repetition
---
modules/shared.py | 190 +++++++++++++++++++++++-----------------------
1 file changed, 97 insertions(+), 93 deletions(-)
diff --git a/modules/shared.py b/modules/shared.py
index f4f8e180..08200399 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -9,6 +9,7 @@ from pathlib import Path
import yaml
from modules.logging_colors import logger
+from modules.presets import default_preset
# Model variables
model = None
@@ -28,99 +29,6 @@ gradio = {}
persistent_interface_state = {}
need_restart = False
-# UI defaults
-settings = {
- 'show_controls': True,
- 'start_with': '',
- 'mode': 'instruct',
- 'chat_style': 'cai-chat',
- 'chat-instruct_command': 'Continue the chat dialogue below. Write a single reply for the character "<|character|>".\n\n<|prompt|>',
- 'enable_web_search': False,
- 'web_search_pages': 3,
- 'prompt-default': 'QA',
- 'prompt-notebook': 'QA',
- 'preset': 'min_p',
- 'max_new_tokens': 512,
- 'max_new_tokens_min': 1,
- 'max_new_tokens_max': 4096,
- 'prompt_lookup_num_tokens': 0,
- 'max_tokens_second': 0,
- 'auto_max_new_tokens': True,
- 'ban_eos_token': False,
- 'add_bos_token': True,
- 'enable_thinking': True,
- 'skip_special_tokens': True,
- 'stream': True,
- 'static_cache': False,
- 'truncation_length': 8192,
- 'seed': -1,
- 'custom_stopping_strings': '',
- 'custom_token_bans': '',
- 'negative_prompt': '',
- 'dark_theme': True,
- 'default_extensions': [],
-
- # Character settings
- 'character': 'Assistant',
- 'name1': 'You',
- 'name2': 'AI',
- 'user_bio': '',
- 'context': 'The following is a conversation with an AI Large Language Model. The AI has been trained to answer questions, provide recommendations, and help with decision making. The AI follows user requests. The AI thinks outside the box.',
- 'greeting': 'How can I help you today?',
- 'custom_system_message': '',
- 'instruction_template_str': "{%- set ns = namespace(found=false) -%}\n{%- for message in messages -%}\n {%- if message['role'] == 'system' -%}\n {%- set ns.found = true -%}\n {%- endif -%}\n{%- endfor -%}\n{%- if not ns.found -%}\n {{- '' + 'Below is an instruction that describes a task. Write a response that appropriately completes the request.' + '\\n\\n' -}}\n{%- endif %}\n{%- for message in messages %}\n {%- if message['role'] == 'system' -%}\n {{- '' + message['content'] + '\\n\\n' -}}\n {%- else -%}\n {%- if message['role'] == 'user' -%}\n {{-'### Instruction:\\n' + message['content'] + '\\n\\n'-}}\n {%- else -%}\n {{-'### Response:\\n' + message['content'] + '\\n\\n' -}}\n {%- endif -%}\n {%- endif -%}\n{%- endfor -%}\n{%- if add_generation_prompt -%}\n {{-'### Response:\\n'-}}\n{%- endif -%}",
- 'chat_template_str': "{%- for message in messages %}\n {%- if message['role'] == 'system' -%}\n {%- if message['content'] -%}\n {{- message['content'] + '\\n\\n' -}}\n {%- endif -%}\n {%- if user_bio -%}\n {{- user_bio + '\\n\\n' -}}\n {%- endif -%}\n {%- else -%}\n {%- if message['role'] == 'user' -%}\n {{- name1 + ': ' + message['content'] + '\\n'-}}\n {%- else -%}\n {{- name2 + ': ' + message['content'] + '\\n' -}}\n {%- endif -%}\n {%- endif -%}\n{%- endfor -%}",
-
- # Generation parameters - Curve shape
- 'temperature': 1.0,
- 'dynatemp_low': 1.0,
- 'dynatemp_high': 1.0,
- 'dynatemp_exponent': 1.0,
- 'smoothing_factor': 0.0,
- 'smoothing_curve': 1.0,
-
- # Generation parameters - Curve cutoff
- 'min_p': 0.0,
- 'top_p': 1.0,
- 'top_k': 0,
- 'typical_p': 1.0,
- 'xtc_threshold': 0.1,
- 'xtc_probability': 0.0,
- 'epsilon_cutoff': 0.0,
- 'eta_cutoff': 0.0,
- 'tfs': 1.0,
- 'top_a': 0.0,
- 'top_n_sigma': 0.0,
-
- # Generation parameters - Repetition suppression
- 'dry_multiplier': 0.0,
- 'dry_allowed_length': 2,
- 'dry_base': 1.75,
- 'repetition_penalty': 1.0,
- 'frequency_penalty': 0.0,
- 'presence_penalty': 0.0,
- 'encoder_repetition_penalty': 1.0,
- 'no_repeat_ngram_size': 0,
- 'repetition_penalty_range': 1024,
-
- # Generation parameters - Alternative sampling methods
- 'penalty_alpha': 0.0,
- 'guidance_scale': 1.0,
- 'mirostat_mode': 0,
- 'mirostat_tau': 5.0,
- 'mirostat_eta': 0.1,
-
- # Generation parameters - Other options
- 'do_sample': True,
- 'dynamic_temperature': False,
- 'temperature_last': False,
- 'sampler_priority': 'repetition_penalty\npresence_penalty\nfrequency_penalty\ndry\ntop_n_sigma\ntemperature\ndynamic_temperature\nquadratic_sampling\ntop_k\ntop_p\ntypical_p\nepsilon_cutoff\neta_cutoff\ntfs\ntop_a\nmin_p\nmirostat\nxtc\nencoder_repetition_penalty\nno_repeat_ngram',
- 'dry_sequence_breakers': '"\\n", ":", "\\"", "*"',
- 'grammar_string': '',
-}
-
-default_settings = copy.deepcopy(settings)
-
# Parser copied from https://github.com/vladmandic/automatic
parser = argparse.ArgumentParser(description="Text generation web UI", conflict_handler='resolve', add_help=True, formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=55, indent_increment=2, width=200))
@@ -282,6 +190,102 @@ for arg in sys.argv[1:]:
elif hasattr(args, arg):
provided_arguments.append(arg)
+# Default generation parameters
+neutral_samplers = default_preset()
+
+# UI defaults
+settings = {
+ 'show_controls': True,
+ 'start_with': '',
+ 'mode': 'instruct',
+ 'chat_style': 'cai-chat',
+ 'chat-instruct_command': 'Continue the chat dialogue below. Write a single reply for the character "<|character|>".\n\n<|prompt|>',
+ 'enable_web_search': False,
+ 'web_search_pages': 3,
+ 'prompt-default': 'QA',
+ 'prompt-notebook': 'QA',
+ 'preset': 'min_p',
+ 'max_new_tokens': 512,
+ 'max_new_tokens_min': 1,
+ 'max_new_tokens_max': 4096,
+ 'prompt_lookup_num_tokens': 0,
+ 'max_tokens_second': 0,
+ 'auto_max_new_tokens': True,
+ 'ban_eos_token': False,
+ 'add_bos_token': True,
+ 'enable_thinking': True,
+ 'skip_special_tokens': True,
+ 'stream': True,
+ 'static_cache': False,
+ 'truncation_length': 8192,
+ 'seed': -1,
+ 'custom_stopping_strings': '',
+ 'custom_token_bans': '',
+ 'negative_prompt': '',
+ 'dark_theme': True,
+ 'default_extensions': [],
+
+ # Character settings
+ 'character': 'Assistant',
+ 'name1': 'You',
+ 'name2': 'AI',
+ 'user_bio': '',
+ 'context': 'The following is a conversation with an AI Large Language Model. The AI has been trained to answer questions, provide recommendations, and help with decision making. The AI follows user requests. The AI thinks outside the box.',
+ 'greeting': 'How can I help you today?',
+ 'custom_system_message': '',
+ 'instruction_template_str': "{%- set ns = namespace(found=false) -%}\n{%- for message in messages -%}\n {%- if message['role'] == 'system' -%}\n {%- set ns.found = true -%}\n {%- endif -%}\n{%- endfor -%}\n{%- if not ns.found -%}\n {{- '' + 'Below is an instruction that describes a task. Write a response that appropriately completes the request.' + '\\n\\n' -}}\n{%- endif %}\n{%- for message in messages %}\n {%- if message['role'] == 'system' -%}\n {{- '' + message['content'] + '\\n\\n' -}}\n {%- else -%}\n {%- if message['role'] == 'user' -%}\n {{-'### Instruction:\\n' + message['content'] + '\\n\\n'-}}\n {%- else -%}\n {{-'### Response:\\n' + message['content'] + '\\n\\n' -}}\n {%- endif -%}\n {%- endif -%}\n{%- endfor -%}\n{%- if add_generation_prompt -%}\n {{-'### Response:\\n'-}}\n{%- endif -%}",
+ 'chat_template_str': "{%- for message in messages %}\n {%- if message['role'] == 'system' -%}\n {%- if message['content'] -%}\n {{- message['content'] + '\\n\\n' -}}\n {%- endif -%}\n {%- if user_bio -%}\n {{- user_bio + '\\n\\n' -}}\n {%- endif -%}\n {%- else -%}\n {%- if message['role'] == 'user' -%}\n {{- name1 + ': ' + message['content'] + '\\n'-}}\n {%- else -%}\n {{- name2 + ': ' + message['content'] + '\\n' -}}\n {%- endif -%}\n {%- endif -%}\n{%- endfor -%}",
+
+ # Generation parameters - Curve shape
+ 'temperature': neutral_samplers['temperature'],
+ 'dynatemp_low': neutral_samplers['dynatemp_low'],
+ 'dynatemp_high': neutral_samplers['dynatemp_high'],
+ 'dynatemp_exponent': neutral_samplers['dynatemp_exponent'],
+ 'smoothing_factor': neutral_samplers['smoothing_factor'],
+ 'smoothing_curve': neutral_samplers['smoothing_curve'],
+
+ # Generation parameters - Curve cutoff
+ 'min_p': neutral_samplers['min_p'],
+ 'top_p': neutral_samplers['top_p'],
+ 'top_k': neutral_samplers['top_k'],
+ 'typical_p': neutral_samplers['typical_p'],
+ 'xtc_threshold': neutral_samplers['xtc_threshold'],
+ 'xtc_probability': neutral_samplers['xtc_probability'],
+ 'epsilon_cutoff': neutral_samplers['epsilon_cutoff'],
+ 'eta_cutoff': neutral_samplers['eta_cutoff'],
+ 'tfs': neutral_samplers['tfs'],
+ 'top_a': neutral_samplers['top_a'],
+ 'top_n_sigma': neutral_samplers['top_n_sigma'],
+
+ # Generation parameters - Repetition suppression
+ 'dry_multiplier': neutral_samplers['dry_multiplier'],
+ 'dry_allowed_length': neutral_samplers['dry_allowed_length'],
+ 'dry_base': neutral_samplers['dry_base'],
+ 'repetition_penalty': neutral_samplers['repetition_penalty'],
+ 'frequency_penalty': neutral_samplers['frequency_penalty'],
+ 'presence_penalty': neutral_samplers['presence_penalty'],
+ 'encoder_repetition_penalty': neutral_samplers['encoder_repetition_penalty'],
+ 'no_repeat_ngram_size': neutral_samplers['no_repeat_ngram_size'],
+ 'repetition_penalty_range': neutral_samplers['repetition_penalty_range'],
+
+ # Generation parameters - Alternative sampling methods
+ 'penalty_alpha': neutral_samplers['penalty_alpha'],
+ 'guidance_scale': neutral_samplers['guidance_scale'],
+ 'mirostat_mode': neutral_samplers['mirostat_mode'],
+ 'mirostat_tau': neutral_samplers['mirostat_tau'],
+ 'mirostat_eta': neutral_samplers['mirostat_eta'],
+
+ # Generation parameters - Other options
+ 'do_sample': neutral_samplers['do_sample'],
+ 'dynamic_temperature': neutral_samplers['dynamic_temperature'],
+ 'temperature_last': neutral_samplers['temperature_last'],
+ 'sampler_priority': neutral_samplers['sampler_priority'],
+ 'dry_sequence_breakers': neutral_samplers['dry_sequence_breakers'],
+ 'grammar_string': '',
+}
+
+default_settings = copy.deepcopy(settings)
+
def do_cmd_flags_warnings():
# Security warnings
From fe955cac1fd7298d820e42790e257d9ace1c5eb4 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sat, 7 Jun 2025 22:15:19 -0700
Subject: [PATCH 39/82] Small UI changes
---
css/main.css | 4 ++++
modules/ui_chat.py | 8 ++++----
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/css/main.css b/css/main.css
index 4277519a..7d7b0cbd 100644
--- a/css/main.css
+++ b/css/main.css
@@ -62,6 +62,10 @@ div.svelte-iyf88w {
flex: none;
}
+.refresh-button-medium {
+ max-width: 4.4em;
+}
+
.refresh-button-small {
max-width: 2.2em;
}
diff --git a/modules/ui_chat.py b/modules/ui_chat.py
index f8e2fc32..ef9330e4 100644
--- a/modules/ui_chat.py
+++ b/modules/ui_chat.py
@@ -24,11 +24,11 @@ def create_ui():
with gr.Row(elem_id='past-chats-row', elem_classes=['pretty_scrollbar']):
with gr.Column():
with gr.Row(elem_id='past-chats-buttons'):
- shared.gradio['branch_chat'] = gr.Button('Branch', elem_classes='refresh-button', elem_id='Branch', interactive=not mu)
- shared.gradio['branch_index'] = gr.Number(value=-1, precision=0, visible=False, elem_id="Branch-index", interactive=True)
- shared.gradio['rename_chat'] = gr.Button('Rename', elem_classes='refresh-button', interactive=not mu)
+ shared.gradio['branch_chat'] = gr.Button('Branch', elem_classes=['refresh-button', 'refresh-button-medium'], elem_id='Branch', interactive=not mu)
+ shared.gradio['rename_chat'] = gr.Button('Rename', elem_classes=['refresh-button', 'refresh-button-medium'], interactive=not mu)
shared.gradio['delete_chat'] = gr.Button('🗑️', elem_classes='refresh-button', interactive=not mu)
- shared.gradio['Start new chat'] = gr.Button('New chat', elem_classes=['refresh-button', 'focus-on-chat-input'])
+ shared.gradio['Start new chat'] = gr.Button('New chat', elem_classes=['refresh-button', 'refresh-button-medium', 'focus-on-chat-input'])
+ shared.gradio['branch_index'] = gr.Number(value=-1, precision=0, visible=False, elem_id="Branch-index", interactive=True)
shared.gradio['search_chat'] = gr.Textbox(placeholder='Search chats...', max_lines=1, elem_id='search_chat')
From 0dbc4cbc71e7eed1d51fd9169048a54cb8d2d927 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sat, 7 Jun 2025 22:20:58 -0700
Subject: [PATCH 40/82] Add Qwen3 presets
---
user_data/presets/Qwen3 - No Thinking.yaml | 3 +++
user_data/presets/Qwen3 - Thinking.yaml | 3 +++
2 files changed, 6 insertions(+)
create mode 100644 user_data/presets/Qwen3 - No Thinking.yaml
create mode 100644 user_data/presets/Qwen3 - Thinking.yaml
diff --git a/user_data/presets/Qwen3 - No Thinking.yaml b/user_data/presets/Qwen3 - No Thinking.yaml
new file mode 100644
index 00000000..b1c1e03c
--- /dev/null
+++ b/user_data/presets/Qwen3 - No Thinking.yaml
@@ -0,0 +1,3 @@
+temperature: 0.7
+top_p: 0.8
+top_k: 20
diff --git a/user_data/presets/Qwen3 - Thinking.yaml b/user_data/presets/Qwen3 - Thinking.yaml
new file mode 100644
index 00000000..cb2942f9
--- /dev/null
+++ b/user_data/presets/Qwen3 - Thinking.yaml
@@ -0,0 +1,3 @@
+temperature: 0.6
+top_p: 0.95
+top_k: 20
From 1bdf11b511b69f6eb10f9067847c64d39c8872f4 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sat, 7 Jun 2025 22:23:09 -0700
Subject: [PATCH 41/82] Use the Qwen3 - Thinking preset by default
---
modules/shared.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/modules/shared.py b/modules/shared.py
index 08200399..3794206b 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -204,7 +204,7 @@ settings = {
'web_search_pages': 3,
'prompt-default': 'QA',
'prompt-notebook': 'QA',
- 'preset': 'min_p',
+ 'preset': 'Qwen3 - Thinking' if Path('user_data/presets/Qwen3 - Thinking.yaml').exists() else '',
'max_new_tokens': 512,
'max_new_tokens_min': 1,
'max_new_tokens_max': 4096,
@@ -237,7 +237,7 @@ settings = {
'chat_template_str': "{%- for message in messages %}\n {%- if message['role'] == 'system' -%}\n {%- if message['content'] -%}\n {{- message['content'] + '\\n\\n' -}}\n {%- endif -%}\n {%- if user_bio -%}\n {{- user_bio + '\\n\\n' -}}\n {%- endif -%}\n {%- else -%}\n {%- if message['role'] == 'user' -%}\n {{- name1 + ': ' + message['content'] + '\\n'-}}\n {%- else -%}\n {{- name2 + ': ' + message['content'] + '\\n' -}}\n {%- endif -%}\n {%- endif -%}\n{%- endfor -%}",
# Generation parameters - Curve shape
- 'temperature': neutral_samplers['temperature'],
+ 'temperature': 0.6,
'dynatemp_low': neutral_samplers['dynatemp_low'],
'dynatemp_high': neutral_samplers['dynatemp_high'],
'dynatemp_exponent': neutral_samplers['dynatemp_exponent'],
@@ -246,8 +246,8 @@ settings = {
# Generation parameters - Curve cutoff
'min_p': neutral_samplers['min_p'],
- 'top_p': neutral_samplers['top_p'],
- 'top_k': neutral_samplers['top_k'],
+ 'top_p': 0.95,
+ 'top_k': 20,
'typical_p': neutral_samplers['typical_p'],
'xtc_threshold': neutral_samplers['xtc_threshold'],
'xtc_probability': neutral_samplers['xtc_probability'],
From ae150fa24f204fb56c9fe4e2530435bfcf0ec1d7 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sat, 7 Jun 2025 22:25:46 -0700
Subject: [PATCH 42/82] Remove the null preset
---
user_data/presets/Null preset.yaml | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 user_data/presets/Null preset.yaml
diff --git a/user_data/presets/Null preset.yaml b/user_data/presets/Null preset.yaml
deleted file mode 100644
index 714aa9a3..00000000
--- a/user_data/presets/Null preset.yaml
+++ /dev/null
@@ -1 +0,0 @@
-temperature: 1
From 1cab149c1a020c86f215bafd48b809cbc02a225b Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sat, 7 Jun 2025 22:26:13 -0700
Subject: [PATCH 43/82] Remove the contrastive search preset
---
user_data/presets/Contrastive Search.yaml | 3 ---
1 file changed, 3 deletions(-)
delete mode 100644 user_data/presets/Contrastive Search.yaml
diff --git a/user_data/presets/Contrastive Search.yaml b/user_data/presets/Contrastive Search.yaml
deleted file mode 100644
index d9a47a9f..00000000
--- a/user_data/presets/Contrastive Search.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-do_sample: false
-top_k: 4
-penalty_alpha: 0.3
From af6bb7513afc6a45cba1716a8cd665d4ee264779 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sun, 8 Jun 2025 09:09:36 -0700
Subject: [PATCH 44/82] Add back the "Save UI defaults" button
It's useful for saving extensions settings.
---
modules/ui_session.py | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/modules/ui_session.py b/modules/ui_session.py
index 4ed740cd..db9ce3b0 100644
--- a/modules/ui_session.py
+++ b/modules/ui_session.py
@@ -12,6 +12,7 @@ def create_ui():
with gr.Column():
with gr.Row():
shared.gradio['toggle_dark_mode'] = gr.Button('Toggle 💡')
+ shared.gradio['save_settings'] = gr.Button('Save UI defaults to user_data/settings.yaml', interactive=not mu)
shared.gradio['reset_interface'] = gr.Button("Apply flags/extensions and restart", interactive=not mu)
with gr.Row():
@@ -32,14 +33,28 @@ def create_ui():
if not shared.args.portable:
extension_name.submit(clone_or_pull_repository, extension_name, extension_status, show_progress=False)
+ shared.gradio['save_settings'].click(
+ ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
+ handle_save_settings, gradio('interface_state', 'preset_menu', 'extensions_menu', 'show_controls', 'theme_state'), gradio('save_contents', 'save_filename', 'save_root', 'file_saver'), show_progress=False)
+
+ shared.gradio['toggle_dark_mode'].click(
+ lambda x: 'dark' if x == 'light' else 'light', gradio('theme_state'), gradio('theme_state')).then(
+ None, None, None, js=f'() => {{{ui.dark_theme_js}; toggleDarkMode()}}')
+
# Reset interface event
shared.gradio['reset_interface'].click(
set_interface_arguments, gradio('extensions_menu', 'bool_menu'), None).then(
None, None, None, js='() => {document.body.innerHTML=\'
Reloading...
\'; setTimeout(function(){location.reload()},2500); return []}')
- shared.gradio['toggle_dark_mode'].click(
- lambda x: 'dark' if x == 'light' else 'light', gradio('theme_state'), gradio('theme_state')).then(
- None, None, None, js=f'() => {{{ui.dark_theme_js}; toggleDarkMode()}}')
+
+def handle_save_settings(state, preset, extensions, show_controls, theme):
+ contents = ui.save_settings(state, preset, extensions, show_controls, theme)
+ return [
+ contents,
+ "settings.yaml",
+ "user_data/",
+ gr.update(visible=True)
+ ]
def set_interface_arguments(extensions, bool_active):
From 42e7864d6242745263074a08bb4696059650104e Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sun, 8 Jun 2025 09:20:21 -0700
Subject: [PATCH 45/82] Reorganize the Session tab
---
modules/github.py | 38 --------------------------------------
modules/ui_session.py | 19 +++++--------------
modules/utils.py | 3 +--
3 files changed, 6 insertions(+), 54 deletions(-)
delete mode 100644 modules/github.py
diff --git a/modules/github.py b/modules/github.py
deleted file mode 100644
index f3dc26e1..00000000
--- a/modules/github.py
+++ /dev/null
@@ -1,38 +0,0 @@
-import subprocess
-from pathlib import Path
-
-new_extensions = set()
-
-
-def clone_or_pull_repository(github_url):
- global new_extensions
-
- repository_folder = Path("extensions")
- repo_name = github_url.rstrip("/").split("/")[-1].split(".")[0]
-
- # Check if the repository folder exists
- if not repository_folder.exists():
- repository_folder.mkdir(parents=True)
-
- repo_path = repository_folder / repo_name
-
- # Check if the repository is already cloned
- if repo_path.exists():
- yield f"Updating {github_url}..."
- # Perform a 'git pull' to update the repository
- try:
- pull_output = subprocess.check_output(["git", "-C", repo_path, "pull"], stderr=subprocess.STDOUT)
- yield "Done."
- return pull_output.decode()
- except subprocess.CalledProcessError as e:
- return str(e)
-
- # Clone the repository
- try:
- yield f"Cloning {github_url}..."
- clone_output = subprocess.check_output(["git", "clone", github_url, repo_path], stderr=subprocess.STDOUT)
- new_extensions.add(repo_name)
- yield f"The extension `{repo_name}` has been downloaded.\n\nPlease close the web UI completely and launch it again to be able to load it."
- return clone_output.decode()
- except subprocess.CalledProcessError as e:
- return str(e)
diff --git a/modules/ui_session.py b/modules/ui_session.py
index db9ce3b0..086a06bf 100644
--- a/modules/ui_session.py
+++ b/modules/ui_session.py
@@ -1,7 +1,6 @@
import gradio as gr
from modules import shared, ui, utils
-from modules.github import clone_or_pull_repository
from modules.utils import gradio
@@ -10,10 +9,12 @@ def create_ui():
with gr.Tab("Session", elem_id="session-tab"):
with gr.Row():
with gr.Column():
- with gr.Row():
- shared.gradio['toggle_dark_mode'] = gr.Button('Toggle 💡')
- shared.gradio['save_settings'] = gr.Button('Save UI defaults to user_data/settings.yaml', interactive=not mu)
+ gr.Markdown("## Settings")
+ shared.gradio['save_settings'] = gr.Button('Save settings to user_data/settings.yaml', elem_classes='refresh-button', interactive=not mu)
+ shared.gradio['toggle_dark_mode'] = gr.Button('Toggle light/dark theme 💡', elem_classes='refresh-button')
+ with gr.Column():
+ gr.Markdown("## Extensions & flags")
shared.gradio['reset_interface'] = gr.Button("Apply flags/extensions and restart", interactive=not mu)
with gr.Row():
with gr.Column():
@@ -22,17 +23,7 @@ def create_ui():
with gr.Column():
shared.gradio['bool_menu'] = gr.CheckboxGroup(choices=get_boolean_arguments(), value=get_boolean_arguments(active=True), label="Boolean command-line flags", elem_classes='checkboxgroup-table')
- with gr.Column():
- if not shared.args.portable:
- 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.', interactive=not mu)
- extension_status = gr.Markdown()
- else:
- pass
-
shared.gradio['theme_state'] = gr.Textbox(visible=False, value='dark' if shared.settings['dark_theme'] else 'light')
- if not shared.args.portable:
- extension_name.submit(clone_or_pull_repository, extension_name, extension_status, show_progress=False)
-
shared.gradio['save_settings'].click(
ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
handle_save_settings, gradio('interface_state', 'preset_menu', 'extensions_menu', 'show_controls', 'theme_state'), gradio('save_contents', 'save_filename', 'save_root', 'file_saver'), show_progress=False)
diff --git a/modules/utils.py b/modules/utils.py
index 577c55b8..21873541 100644
--- a/modules/utils.py
+++ b/modules/utils.py
@@ -3,7 +3,7 @@ import re
from datetime import datetime
from pathlib import Path
-from modules import github, shared
+from modules import shared
from modules.logging_colors import logger
@@ -182,7 +182,6 @@ def get_available_instruction_templates():
def get_available_extensions():
extensions = sorted(set(map(lambda x: x.parts[1], Path('extensions').glob('*/script.py'))), key=natural_keys)
- extensions = [v for v in extensions if v not in github.new_extensions]
return extensions
From 84f66484c524c41d172abe341b206d31598ef40b Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sun, 8 Jun 2025 09:31:38 -0700
Subject: [PATCH 46/82] Make it optional to paste long pasted content to an
attachment
---
js/main.js | 2 +-
modules/shared.py | 1 +
modules/ui.py | 6 ++++++
modules/ui_session.py | 1 +
4 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/js/main.js b/js/main.js
index 9a620fa9..7e2a457c 100644
--- a/js/main.js
+++ b/js/main.js
@@ -884,7 +884,7 @@ function setupPasteHandler() {
textbox.addEventListener("paste", async (event) => {
const text = event.clipboardData?.getData("text");
- if (text && text.length > MAX_PLAIN_TEXT_LENGTH) {
+ if (text && text.length > MAX_PLAIN_TEXT_LENGTH && document.querySelector("#paste_to_attachment input[data-testid=\"checkbox\"]")?.checked) {
event.preventDefault();
const file = new File([text], "pasted_text.txt", {
diff --git a/modules/shared.py b/modules/shared.py
index 3794206b..59c7dbcd 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -223,6 +223,7 @@ settings = {
'custom_token_bans': '',
'negative_prompt': '',
'dark_theme': True,
+ 'paste_to_attachment': False,
'default_extensions': [],
# Character settings
diff --git a/modules/ui.py b/modules/ui.py
index 8ec4b165..46403dd9 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -268,6 +268,11 @@ def list_interface_input_elements():
# Model elements
elements += list_model_elements()
+ # Other elements
+ elements += [
+ 'paste_to_attachment'
+ ]
+
return elements
@@ -473,6 +478,7 @@ def setup_auto_save():
# Session tab (ui_session.py)
'show_controls',
'theme_state',
+ 'paste_to_attachment'
]
for element_name in change_elements:
diff --git a/modules/ui_session.py b/modules/ui_session.py
index 086a06bf..2ece2251 100644
--- a/modules/ui_session.py
+++ b/modules/ui_session.py
@@ -12,6 +12,7 @@ def create_ui():
gr.Markdown("## Settings")
shared.gradio['save_settings'] = gr.Button('Save settings to user_data/settings.yaml', elem_classes='refresh-button', interactive=not mu)
shared.gradio['toggle_dark_mode'] = gr.Button('Toggle light/dark theme 💡', elem_classes='refresh-button')
+ shared.gradio['paste_to_attachment'] = gr.Checkbox(label='Turn long pasted text into attachments in the Chat tab', value=shared.settings['paste_to_attachment'], elem_id='paste_to_attachment')
with gr.Column():
gr.Markdown("## Extensions & flags")
From 1f1435997a65b92c498f6d5512683a6ee2f21b26 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sun, 8 Jun 2025 09:37:54 -0700
Subject: [PATCH 47/82] Don't show the new 'Restore character' button in the
Chat tab
---
js/main.js | 2 ++
modules/chat.py | 2 +-
modules/ui_chat.py | 6 +++---
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/js/main.js b/js/main.js
index 7e2a457c..70afabe3 100644
--- a/js/main.js
+++ b/js/main.js
@@ -555,6 +555,7 @@ function moveToChatTab() {
newParent.insertBefore(grandParent, newParent.children[newPosition]);
document.getElementById("save-character").style.display = "none";
+ document.getElementById("restore-character").style.display = "none";
}
function restoreOriginalPosition() {
@@ -566,6 +567,7 @@ function restoreOriginalPosition() {
}
document.getElementById("save-character").style.display = "";
+ document.getElementById("restore-character").style.display = "";
movedElement.style.display = "";
movedElement.children[0].style.minWidth = "";
}
diff --git a/modules/chat.py b/modules/chat.py
index f740db55..49511af1 100644
--- a/modules/chat.py
+++ b/modules/chat.py
@@ -1220,7 +1220,7 @@ def load_character(character, name1, name2):
return name1, name2, picture, greeting, context
-def reset_character_for_ui(state):
+def restore_character_for_ui(state):
"""Reset character fields to the currently loaded character's saved values"""
if state['character_menu'] and state['character_menu'] != 'None':
try:
diff --git a/modules/ui_chat.py b/modules/ui_chat.py
index ef9330e4..d7a5ec69 100644
--- a/modules/ui_chat.py
+++ b/modules/ui_chat.py
@@ -122,7 +122,7 @@ def create_chat_settings_ui():
ui.create_refresh_button(shared.gradio['character_menu'], lambda: None, lambda: {'choices': utils.get_available_characters()}, 'refresh-button', interactive=not mu)
shared.gradio['save_character'] = gr.Button('💾', elem_classes='refresh-button', elem_id="save-character", interactive=not mu)
shared.gradio['delete_character'] = gr.Button('🗑️', elem_classes='refresh-button', interactive=not mu)
- shared.gradio['reset_character'] = gr.Button('Restore character', elem_classes='refresh-button', interactive=True)
+ shared.gradio['restore_character'] = gr.Button('Restore character', elem_classes='refresh-button', interactive=True, elem_id='restore-character')
shared.gradio['name2'] = gr.Textbox(value=shared.settings['name2'], lines=1, label='Character\'s name')
shared.gradio['context'] = gr.Textbox(value=shared.settings['context'], lines=10, label='Context', elem_classes=['add_scrollbar'])
@@ -320,9 +320,9 @@ def create_event_handlers():
ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
chat.handle_save_template_click, gradio('instruction_template_str'), gradio('save_filename', 'save_root', 'save_contents', 'file_saver'), show_progress=False)
- shared.gradio['reset_character'].click(
+ shared.gradio['restore_character'].click(
ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
- chat.reset_character_for_ui, gradio('interface_state'), gradio('interface_state', 'name2', 'context', 'greeting', 'character_picture'), show_progress=False)
+ chat.restore_character_for_ui, gradio('interface_state'), gradio('interface_state', 'name2', 'context', 'greeting', 'character_picture'), show_progress=False)
shared.gradio['delete_template'].click(chat.handle_delete_template_click, gradio('instruction_template'), gradio('delete_filename', 'delete_root', 'file_deleter'), show_progress=False)
shared.gradio['save_chat_history'].click(
From 78899244d5e1e6504a5be88252b17e44a48b6ca7 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sun, 8 Jun 2025 09:40:09 -0700
Subject: [PATCH 48/82] Remove settings-template.yaml
---
user_data/settings-template.yaml | 76 --------------------------------
1 file changed, 76 deletions(-)
delete mode 100644 user_data/settings-template.yaml
diff --git a/user_data/settings-template.yaml b/user_data/settings-template.yaml
deleted file mode 100644
index db481e84..00000000
--- a/user_data/settings-template.yaml
+++ /dev/null
@@ -1,76 +0,0 @@
-show_controls: true
-start_with: ''
-mode: instruct
-chat_style: cai-chat
-chat-instruct_command: |-
- Continue the chat dialogue below. Write a single reply for the character "<|character|>".
-
- <|prompt|>
-prompt-default: QA
-prompt-notebook: QA
-character: Assistant
-name1: You
-user_bio: ''
-custom_system_message: ''
-preset: min_p
-max_new_tokens: 512
-max_new_tokens_min: 1
-max_new_tokens_max: 4096
-prompt_lookup_num_tokens: 0
-max_tokens_second: 0
-auto_max_new_tokens: true
-ban_eos_token: false
-add_bos_token: true
-enable_thinking: true
-skip_special_tokens: true
-stream: true
-static_cache: false
-truncation_length: 8192
-seed: -1
-custom_stopping_strings: ''
-custom_token_bans: ''
-negative_prompt: ''
-dark_theme: true
-default_extensions: []
-instruction_template_str: |-
- {%- set ns = namespace(found=false) -%}
- {%- for message in messages -%}
- {%- if message['role'] == 'system' -%}
- {%- set ns.found = true -%}
- {%- endif -%}
- {%- endfor -%}
- {%- if not ns.found -%}
- {{- '' + 'Below is an instruction that describes a task. Write a response that appropriately completes the request.' + '\n\n' -}}
- {%- endif %}
- {%- for message in messages %}
- {%- if message['role'] == 'system' -%}
- {{- '' + message['content'] + '\n\n' -}}
- {%- else -%}
- {%- if message['role'] == 'user' -%}
- {{-'### Instruction:\n' + message['content'] + '\n\n'-}}
- {%- else -%}
- {{-'### Response:\n' + message['content'] + '\n\n' -}}
- {%- endif -%}
- {%- endif -%}
- {%- endfor -%}
- {%- if add_generation_prompt -%}
- {{-'### Response:\n'-}}
- {%- endif -%}
-chat_template_str: |-
- {%- for message in messages %}
- {%- if message['role'] == 'system' -%}
- {%- if message['content'] -%}
- {{- message['content'] + '\n\n' -}}
- {%- endif -%}
- {%- if user_bio -%}
- {{- user_bio + '\n\n' -}}
- {%- endif -%}
- {%- else -%}
- {%- if message['role'] == 'user' -%}
- {{- name1 + ': ' + message['content'] + '\n'-}}
- {%- else -%}
- {{- name2 + ': ' + message['content'] + '\n' -}}
- {%- endif -%}
- {%- endif -%}
- {%- endfor -%}
-
From eb0ab9db1d285fb3be949c4180e63d7df30e61a0 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sun, 8 Jun 2025 15:04:05 -0700
Subject: [PATCH 49/82] Fix light/dark theme persistence across page reloads
---
modules/ui_session.py | 2 +-
server.py | 25 ++++++++++++++++++++-----
2 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/modules/ui_session.py b/modules/ui_session.py
index 2ece2251..33d7dcb7 100644
--- a/modules/ui_session.py
+++ b/modules/ui_session.py
@@ -31,7 +31,7 @@ def create_ui():
shared.gradio['toggle_dark_mode'].click(
lambda x: 'dark' if x == 'light' else 'light', gradio('theme_state'), gradio('theme_state')).then(
- None, None, None, js=f'() => {{{ui.dark_theme_js}; toggleDarkMode()}}')
+ None, None, None, js=f'() => {{{ui.dark_theme_js}; toggleDarkMode(); localStorage.setItem("theme", document.body.classList.contains("dark") ? "dark" : "light")}}')
# Reset interface event
shared.gradio['reset_interface'].click(
diff --git a/server.py b/server.py
index 3dd0a3f3..bd440fe0 100644
--- a/server.py
+++ b/server.py
@@ -163,11 +163,26 @@ def create_interface():
gradio('show_controls'),
None,
js=f"""(x) => {{
- if ({str(shared.settings['dark_theme']).lower()}) {{
- document.getElementsByTagName('body')[0].classList.add('dark');
- }}
- else {{
- document.getElementsByTagName('body')[0].classList.remove('dark');
+ // Check if this is first visit or if localStorage is out of sync
+ const savedTheme = localStorage.getItem('theme');
+ const serverTheme = {str(shared.settings['dark_theme']).lower()} ? 'dark' : 'light';
+
+ // If no saved theme or mismatch with server on first load, use server setting
+ if (!savedTheme || !sessionStorage.getItem('theme_synced')) {{
+ localStorage.setItem('theme', serverTheme);
+ sessionStorage.setItem('theme_synced', 'true');
+ if (serverTheme === 'dark') {{
+ document.getElementsByTagName('body')[0].classList.add('dark');
+ }} else {{
+ document.getElementsByTagName('body')[0].classList.remove('dark');
+ }}
+ }} else {{
+ // Use localStorage for subsequent reloads
+ if (savedTheme === 'dark') {{
+ document.getElementsByTagName('body')[0].classList.add('dark');
+ }} else {{
+ document.getElementsByTagName('body')[0].classList.remove('dark');
+ }}
}}
{js}
{ui.show_controls_js}
From f81b1540caf324923eeb1bec75c9ce8774865e38 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sun, 8 Jun 2025 15:19:25 -0700
Subject: [PATCH 50/82] Small style improvements
---
css/main.css | 2 +-
modules/ui.py | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/css/main.css b/css/main.css
index 7d7b0cbd..e2ce4801 100644
--- a/css/main.css
+++ b/css/main.css
@@ -269,7 +269,7 @@ button {
.dark .pretty_scrollbar::-webkit-scrollbar-thumb,
.dark .pretty_scrollbar::-webkit-scrollbar-thumb:hover {
- background: rgb(255 255 255 / 10%);
+ background: rgb(255 255 255 / 6.25%);
border-radius: 10px;
}
diff --git a/modules/ui.py b/modules/ui.py
index 46403dd9..458b18ed 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -74,8 +74,10 @@ if not shared.args.old_colors:
body_background_fill="white",
block_background_fill="transparent",
body_text_color='rgb(64, 64, 64)',
- button_secondary_background_fill="#f4f4f4",
+ button_secondary_background_fill="white",
button_secondary_border_color="var(--border-color-primary)",
+ input_shadow="none",
+ button_shadow_hover="none",
# Dark Mode Colors
input_background_fill_dark='var(--darker-gray)',
From ff01bcb870e6a5bca6b11f32d522911b5f2ccf40 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sun, 8 Jun 2025 15:33:05 -0700
Subject: [PATCH 51/82] Use user_data/cache/gradio for Gradio temp files
---
server.py | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/server.py b/server.py
index bd440fe0..e178e8fe 100644
--- a/server.py
+++ b/server.py
@@ -1,12 +1,26 @@
import os
+import shutil
import warnings
+from pathlib import Path
from modules import shared
from modules.block_requests import OpenMonkeyPatch, RequestBlocker
from modules.logging_colors import logger
-os.environ['GRADIO_ANALYTICS_ENABLED'] = 'False'
-os.environ['BITSANDBYTES_NOWELCOME'] = '1'
+# Set up Gradio temp directory path
+gradio_temp_path = Path('user_data') / 'cache' / 'gradio'
+
+# Set environment variables
+os.environ.update({
+ 'GRADIO_ANALYTICS_ENABLED': 'False',
+ 'BITSANDBYTES_NOWELCOME': '1',
+ 'GRADIO_TEMP_DIR': str(gradio_temp_path)
+})
+
+# Clear and recreate gradio temp directory
+shutil.rmtree(gradio_temp_path, ignore_errors=True)
+gradio_temp_path.mkdir(parents=True, exist_ok=True)
+
warnings.filterwarnings('ignore', category=UserWarning, message='TypedStorage is deprecated')
warnings.filterwarnings('ignore', category=UserWarning, message='Using the update method is deprecated')
warnings.filterwarnings('ignore', category=UserWarning, message='Field "model_name" has conflict')
@@ -27,7 +41,6 @@ import signal
import sys
import time
from functools import partial
-from pathlib import Path
from threading import Lock, Thread
import yaml
From 7ed1926ce7a37d1ccd6b6c8be399581a258759a5 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sun, 8 Jun 2025 15:38:40 -0700
Subject: [PATCH 52/82] Small change after previous commit
---
server.py | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/server.py b/server.py
index e178e8fe..5cad1d8a 100644
--- a/server.py
+++ b/server.py
@@ -9,6 +9,8 @@ from modules.logging_colors import logger
# Set up Gradio temp directory path
gradio_temp_path = Path('user_data') / 'cache' / 'gradio'
+shutil.rmtree(gradio_temp_path, ignore_errors=True)
+gradio_temp_path.mkdir(parents=True, exist_ok=True)
# Set environment variables
os.environ.update({
@@ -17,10 +19,6 @@ os.environ.update({
'GRADIO_TEMP_DIR': str(gradio_temp_path)
})
-# Clear and recreate gradio temp directory
-shutil.rmtree(gradio_temp_path, ignore_errors=True)
-gradio_temp_path.mkdir(parents=True, exist_ok=True)
-
warnings.filterwarnings('ignore', category=UserWarning, message='TypedStorage is deprecated')
warnings.filterwarnings('ignore', category=UserWarning, message='Using the update method is deprecated')
warnings.filterwarnings('ignore', category=UserWarning, message='Field "model_name" has conflict')
From e976a5ddc7598de49227f600515a7eee72fc1af6 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sun, 8 Jun 2025 17:34:56 -0700
Subject: [PATCH 53/82] Re-highlight code blocks when switching light/dark
themes
---
js/dark_theme.js | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/js/dark_theme.js b/js/dark_theme.js
index b540fb11..f61060cd 100644
--- a/js/dark_theme.js
+++ b/js/dark_theme.js
@@ -6,4 +6,11 @@ function toggleDarkMode() {
} else {
currentCSS.setAttribute("href", "file/css/highlightjs/github-dark.min.css");
}
+
+ // Re-highlight all code blocks once stylesheet loads
+ currentCSS.onload = function() {
+ document.querySelectorAll("pre code").forEach(block => {
+ hljs.highlightElement(block);
+ });
+ };
}
From b5e021fc49c840d1ac934f647b64317918ee1208 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sun, 8 Jun 2025 17:44:04 -0700
Subject: [PATCH 54/82] Make the dark theme darker
---
css/main.css | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/css/main.css b/css/main.css
index e2ce4801..d04ff624 100644
--- a/css/main.css
+++ b/css/main.css
@@ -1,11 +1,11 @@
:root {
- --darker-gray: #202123;
- --dark-gray: #2A2B32;
- --light-gray: #373943;
+ --darker-gray: #1C1C1D;
+ --dark-gray: #212125;
+ --light-gray: #2C2E34;
--light-theme-gray: #f9fbff;
--border-color-dark: #525252;
--header-width: 112px;
- --selected-item-color-dark: #2E2F38;
+ --selected-item-color-dark: #282930;
}
@font-face {
From 06dfb7e772a943c1bfdeff6d125d8cf056dc3b73 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sun, 8 Jun 2025 18:03:07 -0700
Subject: [PATCH 55/82] Improve the style of the hover menu
---
css/main.css | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/css/main.css b/css/main.css
index d04ff624..8e57db89 100644
--- a/css/main.css
+++ b/css/main.css
@@ -745,16 +745,13 @@ div.svelte-362y77>*, div.svelte-362y77>.form>* {
justify-content: space-between;
margin: 0 !important;
height: 36px;
+ border-color: transparent !important;
}
.hover-menu button:not(#clear-history-confirm) {
border-bottom: 0 !important;
}
-.hover-menu button:not(#clear-history-confirm):last-child {
- border-bottom: var(--button-border-width) solid var(--border-color-primary) !important;
-}
-
.hover-menu button:hover {
background: #dbeafe !important;
}
@@ -764,26 +761,30 @@ div.svelte-362y77>*, div.svelte-362y77>.form>* {
}
#show-controls {
+ background-color: white;
+ border-color: transparent !important;
height: 36px;
- border-top: 1px solid var(--border-color-dark) !important;
- border-left: 1px solid var(--border-color-dark) !important;
- border-right: 1px solid var(--border-color-dark) !important;
border-radius: 0;
border-bottom: 0 !important;
- background-color: var(--darker-gray);
padding-top: 3px;
padding-left: 4px;
display: flex;
+ font-weight: normal;
+}
+
+.dark #show-controls {
+ background-color: var(--darker-gray);
}
#show-controls label {
display: flex;
flex-direction: row-reverse;
- font-weight: bold;
justify-content: start;
width: 100%;
padding-right: 12px;
gap: 10px;
+ font-weight: 600;
+ color: var(--button-secondary-text-color);
}
#show-controls label input {
From 0b8d2d65a262271e74697410c6aff577cad2594a Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sun, 8 Jun 2025 18:11:27 -0700
Subject: [PATCH 56/82] Minor style improvement
---
modules/ui.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/modules/ui.py b/modules/ui.py
index 458b18ed..ea36c639 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -109,6 +109,7 @@ if not shared.args.old_colors:
button_large_radius='0.375rem',
button_large_padding='6px 12px',
input_radius='0.375rem',
+ block_radius='0',
)
if Path("user_data/notification.mp3").exists():
From 4a369e070aab9e540187bf456a83df5478565a0e Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sun, 8 Jun 2025 18:47:48 -0700
Subject: [PATCH 57/82] Add buttons for easily deleting past chats
---
css/main.css | 53 +++++++++++++++++++++++++++++++++++
js/main.js | 70 ++++++++++++++++++++++++++++++++++++++++++++++
modules/chat.py | 1 -
modules/ui_chat.py | 10 +++----
4 files changed, 127 insertions(+), 7 deletions(-)
diff --git a/css/main.css b/css/main.css
index 8e57db89..c5460eb7 100644
--- a/css/main.css
+++ b/css/main.css
@@ -1570,3 +1570,56 @@ button:focus {
.svelte-sa48pu.stretch:has(> .hidden:only-child) {
display: none;
}
+
+.delete-container {
+ position: absolute;
+ right: 8px;
+ display: flex;
+ gap: 6px;
+ opacity: 0;
+ transition: opacity 0.2s;
+ margin-left: 0;
+}
+
+.chat-label-with-delete {
+ position: relative;
+ padding-right: 60px;
+}
+
+.trash-btn {
+ border: none;
+ background: none;
+ cursor: pointer;
+ padding: 2px;
+ opacity: 0.7;
+}
+
+.cancel-btn {
+ border: none;
+ background: #ef4444;
+ color: white;
+ cursor: pointer;
+ width: 20px;
+ height: 20px;
+ border-radius: 2px;
+ font-family: monospace;
+ font-size: 12px;
+ align-items: center;
+ justify-content: center;
+ display: none;
+}
+
+.confirm-btn {
+ border: none;
+ background: #22c55e;
+ color: white;
+ cursor: pointer;
+ width: 20px;
+ height: 20px;
+ border-radius: 2px;
+ font-family: monospace;
+ font-size: 12px;
+ align-items: center;
+ justify-content: center;
+ display: none;
+}
diff --git a/js/main.js b/js/main.js
index 70afabe3..e9ca5a0b 100644
--- a/js/main.js
+++ b/js/main.js
@@ -917,3 +917,73 @@ document.querySelector("#chat-input .upload-button").title = "Upload text files,
// Activate web search
document.getElementById("web-search").title = "Search the internet with DuckDuckGo";
+
+//------------------------------------------------
+// Inline icons for deleting past chats
+//------------------------------------------------
+
+function addMiniDeletes() {
+ document.querySelectorAll("#past-chats label:not(.has-delete)").forEach(label => {
+ const container = document.createElement("span");
+ container.className = "delete-container";
+
+ label.classList.add("chat-label-with-delete");
+
+ const trashBtn = document.createElement("button");
+ trashBtn.innerHTML = "🗑️";
+ trashBtn.className = "trash-btn";
+
+ const cancelBtn = document.createElement("button");
+ cancelBtn.innerHTML = "✕";
+ cancelBtn.className = "cancel-btn";
+
+ const confirmBtn = document.createElement("button");
+ confirmBtn.innerHTML = "✓";
+ confirmBtn.className = "confirm-btn";
+
+ label.addEventListener("mouseenter", () => {
+ container.style.opacity = "1";
+ });
+
+ label.addEventListener("mouseleave", () => {
+ container.style.opacity = "0";
+ });
+
+ trashBtn.onclick = (e) => {
+ e.stopPropagation();
+ label.querySelector("input").click();
+ document.querySelector("#delete_chat").click();
+ trashBtn.style.display = "none";
+ cancelBtn.style.display = "flex";
+ confirmBtn.style.display = "flex";
+ };
+
+ cancelBtn.onclick = (e) => {
+ e.stopPropagation();
+ document.querySelector("#delete_chat-cancel").click();
+ resetButtons();
+ };
+
+ confirmBtn.onclick = (e) => {
+ e.stopPropagation();
+ document.querySelector("#delete_chat-confirm").click();
+ resetButtons();
+ };
+
+ function resetButtons() {
+ trashBtn.style.display = "inline";
+ cancelBtn.style.display = "none";
+ confirmBtn.style.display = "none";
+ }
+
+ container.append(trashBtn, cancelBtn, confirmBtn);
+ label.appendChild(container);
+ label.classList.add("has-delete");
+ });
+}
+
+new MutationObserver(() => addMiniDeletes()).observe(
+ document.querySelector("#past-chats"),
+ {childList: true, subtree: true}
+);
+addMiniDeletes();
diff --git a/modules/chat.py b/modules/chat.py
index 49511af1..ad5045e0 100644
--- a/modules/chat.py
+++ b/modules/chat.py
@@ -1562,7 +1562,6 @@ def handle_delete_chat_confirm_click(state):
unique_id,
gr.update(visible=False),
gr.update(visible=True),
- gr.update(visible=False)
]
diff --git a/modules/ui_chat.py b/modules/ui_chat.py
index d7a5ec69..428b64c9 100644
--- a/modules/ui_chat.py
+++ b/modules/ui_chat.py
@@ -26,15 +26,15 @@ def create_ui():
with gr.Row(elem_id='past-chats-buttons'):
shared.gradio['branch_chat'] = gr.Button('Branch', elem_classes=['refresh-button', 'refresh-button-medium'], elem_id='Branch', interactive=not mu)
shared.gradio['rename_chat'] = gr.Button('Rename', elem_classes=['refresh-button', 'refresh-button-medium'], interactive=not mu)
- shared.gradio['delete_chat'] = gr.Button('🗑️', elem_classes='refresh-button', interactive=not mu)
+ shared.gradio['delete_chat'] = gr.Button('🗑️', visible=False, elem_classes='refresh-button', interactive=not mu, elem_id='delete_chat')
shared.gradio['Start new chat'] = gr.Button('New chat', elem_classes=['refresh-button', 'refresh-button-medium', 'focus-on-chat-input'])
shared.gradio['branch_index'] = gr.Number(value=-1, precision=0, visible=False, elem_id="Branch-index", interactive=True)
shared.gradio['search_chat'] = gr.Textbox(placeholder='Search chats...', max_lines=1, elem_id='search_chat')
with gr.Row(elem_id='delete-chat-row', visible=False) as shared.gradio['delete-chat-row']:
- shared.gradio['delete_chat-cancel'] = gr.Button('Cancel', elem_classes=['refresh-button', 'focus-on-chat-input'])
- shared.gradio['delete_chat-confirm'] = gr.Button('Confirm', variant='stop', elem_classes=['refresh-button', 'focus-on-chat-input'])
+ shared.gradio['delete_chat-cancel'] = gr.Button('Cancel', elem_classes=['refresh-button', 'focus-on-chat-input'], elem_id='delete_chat-cancel')
+ shared.gradio['delete_chat-confirm'] = gr.Button('Confirm', variant='stop', elem_classes=['refresh-button', 'focus-on-chat-input'], elem_id='delete_chat-confirm')
with gr.Row(elem_id='rename-row', visible=False) as shared.gradio['rename-row']:
shared.gradio['rename_to'] = gr.Textbox(label='Rename to:', placeholder='New name', elem_classes=['no-background'])
@@ -261,11 +261,9 @@ def create_event_handlers():
ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
chat.handle_start_new_chat_click, gradio('interface_state'), gradio('history', 'display', 'unique_id'), show_progress=False)
- shared.gradio['delete_chat'].click(lambda: gr.update(visible=True), None, gradio('delete-chat-row'))
- shared.gradio['delete_chat-cancel'].click(lambda: gr.update(visible=False), None, gradio('delete-chat-row'))
shared.gradio['delete_chat-confirm'].click(
ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
- chat.handle_delete_chat_confirm_click, gradio('interface_state'), gradio('history', 'display', 'unique_id', 'delete-chat-row'), show_progress=False)
+ chat.handle_delete_chat_confirm_click, gradio('interface_state'), gradio('history', 'display', 'unique_id'), show_progress=False)
shared.gradio['branch_chat'].click(
ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
From f3388c2ab4cdf60cbd035d9a021b8e7de1e4665d Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sun, 8 Jun 2025 18:53:04 -0700
Subject: [PATCH 58/82] Fix selecting next chat when deleting with active
search
---
modules/chat.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/modules/chat.py b/modules/chat.py
index ad5045e0..d62bbc42 100644
--- a/modules/chat.py
+++ b/modules/chat.py
@@ -1549,7 +1549,10 @@ def handle_start_new_chat_click(state):
def handle_delete_chat_confirm_click(state):
- index = str(find_all_histories(state).index(state['unique_id']))
+ filtered_histories = find_all_histories_with_first_prompts(state)
+ filtered_ids = [h[1] for h in filtered_histories]
+ index = str(filtered_ids.index(state['unique_id']))
+
delete_history(state['unique_id'], state['character_menu'], state['mode'])
history, unique_id = load_history_after_deletion(state, index)
html = redraw_html(history, state['name1'], state['name2'], state['mode'], state['chat_style'], state['character_menu'])
From f9a007c6a85899d31a9b38baf40fcad5daa0673d Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sun, 8 Jun 2025 19:25:23 -0700
Subject: [PATCH 59/82] Properly filter out failed web search downloads from
attachments
---
modules/web_search.py | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/modules/web_search.py b/modules/web_search.py
index a1e47253..2b6c6c40 100644
--- a/modules/web_search.py
+++ b/modules/web_search.py
@@ -38,7 +38,7 @@ def download_web_page(url, timeout=5):
return text
except Exception as e:
logger.error(f"Error downloading {url}: {e}")
- return f"[Error downloading content from {url}: {str(e)}]"
+ return ""
def perform_web_search(query, num_pages=3, max_workers=5):
@@ -74,9 +74,7 @@ def perform_web_search(query, num_pages=3, max_workers=5):
'url': url,
'content': content
}
- except Exception as e:
- logger.error(f"Error downloading {url}: {e}")
- # Include failed downloads with empty content
+ except Exception:
search_results[index] = {
'title': title,
'url': url,
@@ -108,7 +106,7 @@ def add_web_search_attachments(history, row_idx, user_message, search_query, sta
return
# Filter out failed downloads before adding attachments
- successful_results = [result for result in search_results if result['content'] and result['content'].strip()]
+ successful_results = [result for result in search_results if result['content'].strip()]
if not successful_results:
logger.warning("No successful downloads to add as attachments")
@@ -130,7 +128,7 @@ def add_web_search_attachments(history, row_idx, user_message, search_query, sta
}
history['metadata'][key]["attachments"].append(attachment)
- logger.info(f"Added {len(successful_results)} successful web search results as attachments")
+ logger.info(f"Added {len(successful_results)} successful web search results as attachments.")
except Exception as e:
logger.error(f"Error in web search: {e}")
From 80637cae288dfd218b1bf664e8caedbf473ef298 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sun, 8 Jun 2025 21:55:49 -0700
Subject: [PATCH 60/82] Add version to portable build folder names
---
.github/workflows/build-portable-release-cuda.yml | 9 ++++++---
.github/workflows/build-portable-release-vulkan.yml | 9 ++++++---
.github/workflows/build-portable-release.yml | 9 ++++++---
3 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/.github/workflows/build-portable-release-cuda.yml b/.github/workflows/build-portable-release-cuda.yml
index 571cbac0..283fdd72 100644
--- a/.github/workflows/build-portable-release-cuda.yml
+++ b/.github/workflows/build-portable-release-cuda.yml
@@ -160,16 +160,19 @@ jobs:
rm requirements_cuda_temp.txt
fi
- # 6. Create ZIP file
+ # 6. Move up and rename folder to include version
cd ..
VERSION_CLEAN="${VERSION#v}"
+ mv text-generation-webui text-generation-webui-${VERSION_CLEAN}
+
+ # 7. Create ZIP file
ZIP_NAME="textgen-portable-${VERSION_CLEAN}-${PLATFORM}-cuda${CUDA_VERSION}.zip"
echo "Creating archive: $ZIP_NAME"
if [[ "$RUNNER_OS" == "Windows" ]]; then
- powershell -Command "Compress-Archive -Path text-generation-webui -DestinationPath $ZIP_NAME"
+ powershell -Command "Compress-Archive -Path text-generation-webui-${VERSION_CLEAN} -DestinationPath $ZIP_NAME"
else
- zip -r "$ZIP_NAME" text-generation-webui
+ zip -r "$ZIP_NAME" text-generation-webui-${VERSION_CLEAN}
fi
- name: Upload files to a GitHub release
diff --git a/.github/workflows/build-portable-release-vulkan.yml b/.github/workflows/build-portable-release-vulkan.yml
index 4e88d4d9..c6ab8fa7 100644
--- a/.github/workflows/build-portable-release-vulkan.yml
+++ b/.github/workflows/build-portable-release-vulkan.yml
@@ -146,16 +146,19 @@ jobs:
echo "Installing Python packages from $REQ_FILE..."
$PIP_PATH install --target="./$PACKAGES_PATH" -r "$REQ_FILE"
- # 6. Create ZIP file
+ # 5. Move up and rename folder to include version
cd ..
VERSION_CLEAN="${VERSION#v}"
+ mv text-generation-webui text-generation-webui-${VERSION_CLEAN}
+
+ # 6. Create ZIP file
ZIP_NAME="textgen-portable-${VERSION_CLEAN}-${PLATFORM}-vulkan.zip"
echo "Creating archive: $ZIP_NAME"
if [[ "$RUNNER_OS" == "Windows" ]]; then
- powershell -Command "Compress-Archive -Path text-generation-webui -DestinationPath $ZIP_NAME"
+ powershell -Command "Compress-Archive -Path text-generation-webui-${VERSION_CLEAN} -DestinationPath $ZIP_NAME"
else
- zip -r "$ZIP_NAME" text-generation-webui
+ zip -r "$ZIP_NAME" text-generation-webui-${VERSION_CLEAN}
fi
- name: Upload files to a GitHub release
diff --git a/.github/workflows/build-portable-release.yml b/.github/workflows/build-portable-release.yml
index 6910ce2c..58bfdb25 100644
--- a/.github/workflows/build-portable-release.yml
+++ b/.github/workflows/build-portable-release.yml
@@ -170,16 +170,19 @@ jobs:
echo "Installing Python packages from $REQ_FILE..."
$PIP_PATH install --target="./$PACKAGES_PATH" -r "$REQ_FILE"
- # 5. Create ZIP file
+ # 5. Move up and rename folder to include version
cd ..
VERSION_CLEAN="${VERSION#v}"
+ mv text-generation-webui text-generation-webui-${VERSION_CLEAN}
+
+ # 6. Create ZIP file
ZIP_NAME="textgen-portable-${VERSION_CLEAN}-${PLATFORM}.zip"
echo "Creating archive: $ZIP_NAME"
if [[ "$RUNNER_OS" == "Windows" ]]; then
- powershell -Command "Compress-Archive -Path text-generation-webui -DestinationPath $ZIP_NAME"
+ powershell -Command "Compress-Archive -Path text-generation-webui-${VERSION_CLEAN} -DestinationPath $ZIP_NAME"
else
- zip -r "$ZIP_NAME" text-generation-webui
+ zip -r "$ZIP_NAME" text-generation-webui-${VERSION_CLEAN}
fi
- name: Upload files to a GitHub release
From eefbf96f6a30ad63da6a494b78fbb3e496462d38 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Sun, 8 Jun 2025 22:14:56 -0700
Subject: [PATCH 61/82] Don't save truncation_length to user_data/settings.yaml
---
modules/ui.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/modules/ui.py b/modules/ui.py
index ea36c639..38693da8 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -332,6 +332,7 @@ def save_settings(state, preset, extensions_list, show_controls, theme_state):
output['show_controls'] = show_controls
output['dark_theme'] = True if theme_state == 'dark' else False
output.pop('instruction_template_str')
+ output.pop('truncation_length')
# Save extension values in the UI
for extension_name in extensions_list:
From 1602ac1c8ff640399a8a1eadd0305958a89dfccf Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Mon, 9 Jun 2025 09:03:39 -0700
Subject: [PATCH 62/82] Improve the style of thinking blocks in dark mode
---
css/main.css | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/css/main.css b/css/main.css
index c5460eb7..307d0437 100644
--- a/css/main.css
+++ b/css/main.css
@@ -1337,7 +1337,8 @@ div.svelte-362y77>*, div.svelte-362y77>.form>* {
}
.dark .thinking-block {
- background-color: var(--darker-gray);
+ background-color: transparent;
+ border: 1px solid var(--input-border-color);
}
.thinking-header {
From 14efd420845226706aefb92c74fae33d0a49816c Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Mon, 9 Jun 2025 11:25:36 -0700
Subject: [PATCH 63/82] Improve scroll performance by disabling hover effects
during scroll
---
css/main.css | 5 +++++
js/main.js | 11 ++++++++++-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/css/main.css b/css/main.css
index 307d0437..62dfc05f 100644
--- a/css/main.css
+++ b/css/main.css
@@ -1624,3 +1624,8 @@ button:focus {
justify-content: center;
display: none;
}
+
+/* Disable hover effects while scrolling */
+.chat-parent.scrolling * {
+ pointer-events: none !important;
+}
diff --git a/js/main.js b/js/main.js
index e9ca5a0b..1953a6be 100644
--- a/js/main.js
+++ b/js/main.js
@@ -146,8 +146,12 @@ const targetElement = document.getElementById("chat").parentNode.parentNode.pare
targetElement.classList.add("pretty_scrollbar");
targetElement.classList.add("chat-parent");
let isScrolled = false;
+let scrollTimeout;
targetElement.addEventListener("scroll", function() {
+ // Add scrolling class to disable hover effects
+ targetElement.classList.add("scrolling");
+
let diff = targetElement.scrollHeight - targetElement.clientHeight;
if(Math.abs(targetElement.scrollTop - diff) <= 10 || diff == 0) {
isScrolled = false;
@@ -155,7 +159,12 @@ targetElement.addEventListener("scroll", function() {
isScrolled = true;
}
- doSyntaxHighlighting();
+ // Clear previous timeout and set new one
+ clearTimeout(scrollTimeout);
+ scrollTimeout = setTimeout(() => {
+ targetElement.classList.remove("scrolling");
+ doSyntaxHighlighting(); // Only run after scrolling stops
+ }, 150);
});
From 747a4a0e5647aac2aea40bdb1e8ae0d2705bc027 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Mon, 9 Jun 2025 12:32:10 -0700
Subject: [PATCH 64/82] Reposition the ... typing dots
---
css/main.css | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/css/main.css b/css/main.css
index 62dfc05f..a22fdd95 100644
--- a/css/main.css
+++ b/css/main.css
@@ -668,7 +668,7 @@ div.svelte-362y77>*, div.svelte-362y77>.form>* {
display: none;
position: absolute;
background-color: transparent;
- left: -2px;
+ left: 23px;
top: -5px;
padding: var(--block-padding);
}
From f5a5d0c0cbcca8e18a3a30f678d5d6ae2396c0d9 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Mon, 9 Jun 2025 17:32:25 -0700
Subject: [PATCH 65/82] Add the URL of web attachments to the prompt
---
modules/chat.py | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/modules/chat.py b/modules/chat.py
index d62bbc42..25a0607b 100644
--- a/modules/chat.py
+++ b/modules/chat.py
@@ -223,7 +223,10 @@ def generate_chat_prompt(user_input, state, **kwargs):
for attachment in metadata[user_key]["attachments"]:
filename = attachment.get("name", "file")
content = attachment.get("content", "")
- attachments_text += f"\nName: {filename}\nContents:\n\n=====\n{content}\n=====\n\n"
+ if attachment.get("type") == "text/html" and attachment.get("url"):
+ attachments_text += f"\nName: {filename}\nURL: {attachment['url']}\nContents:\n\n=====\n{content}\n=====\n\n"
+ else:
+ attachments_text += f"\nName: {filename}\nContents:\n\n=====\n{content}\n=====\n\n"
if attachments_text:
enhanced_user_msg = f"{user_msg}\n\nATTACHMENTS:\n{attachments_text}"
@@ -250,7 +253,10 @@ def generate_chat_prompt(user_input, state, **kwargs):
for attachment in metadata[user_key]["attachments"]:
filename = attachment.get("name", "file")
content = attachment.get("content", "")
- attachments_text += f"\nName: {filename}\nContents:\n\n=====\n{content}\n=====\n\n"
+ if attachment.get("type") == "text/html" and attachment.get("url"):
+ attachments_text += f"\nName: {filename}\nURL: {attachment['url']}\nContents:\n\n=====\n{content}\n=====\n\n"
+ else:
+ attachments_text += f"\nName: {filename}\nContents:\n\n=====\n{content}\n=====\n\n"
if attachments_text:
user_input = f"{user_input}\n\nATTACHMENTS:\n{attachments_text}"
From 263b5d5557efd7632f0d02adb6f7f44020f19b41 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Mon, 9 Jun 2025 17:55:26 -0700
Subject: [PATCH 66/82] Use html2text to extract the text of web searches
without losing formatting
---
modules/web_search.py | 36 ++++++++++---------
requirements/full/requirements.txt | 2 +-
requirements/full/requirements_amd.txt | 2 +-
requirements/full/requirements_amd_noavx2.txt | 2 +-
.../full/requirements_apple_intel.txt | 2 +-
.../full/requirements_apple_silicon.txt | 2 +-
requirements/full/requirements_cpu_only.txt | 2 +-
.../full/requirements_cpu_only_noavx2.txt | 2 +-
requirements/full/requirements_cuda128.txt | 2 +-
.../full/requirements_cuda128_noavx2.txt | 2 +-
requirements/full/requirements_noavx2.txt | 2 +-
requirements/full/requirements_nowheels.txt | 2 +-
requirements/portable/requirements.txt | 2 +-
.../portable/requirements_apple_intel.txt | 2 +-
.../portable/requirements_apple_silicon.txt | 2 +-
.../portable/requirements_cpu_only.txt | 2 +-
.../portable/requirements_cpu_only_noavx2.txt | 2 +-
requirements/portable/requirements_noavx2.txt | 2 +-
.../portable/requirements_nowheels.txt | 2 +-
requirements/portable/requirements_vulkan.txt | 2 +-
.../portable/requirements_vulkan_noavx2.txt | 2 +-
21 files changed, 39 insertions(+), 37 deletions(-)
diff --git a/modules/web_search.py b/modules/web_search.py
index 2b6c6c40..ffd7e483 100644
--- a/modules/web_search.py
+++ b/modules/web_search.py
@@ -3,8 +3,6 @@ from concurrent.futures import as_completed
from datetime import datetime
import requests
-from bs4 import BeautifulSoup
-from duckduckgo_search import DDGS
from modules.logging_colors import logger
@@ -14,35 +12,39 @@ def get_current_timestamp():
return datetime.now().strftime('%b %d, %Y %H:%M')
-def download_web_page(url, timeout=5):
- """Download and extract text from a web page"""
+def download_web_page(url, timeout=10):
+ """
+ Download a web page and convert its HTML content to structured Markdown text.
+ """
+ import html2text
+
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
response = requests.get(url, headers=headers, timeout=timeout)
- response.raise_for_status()
+ response.raise_for_status() # Raise an exception for bad status codes
- soup = BeautifulSoup(response.content, 'html.parser')
+ # Initialize the HTML to Markdown converter
+ h = html2text.HTML2Text()
+ h.body_width = 0
- # Remove script and style elements
- for script in soup(["script", "style"]):
- script.decompose()
+ # Convert the HTML to Markdown
+ markdown_text = h.handle(response.text)
- # Get text and clean it up
- text = soup.get_text()
- lines = (line.strip() for line in text.splitlines())
- chunks = (phrase.strip() for line in lines for phrase in line.split(" "))
- text = ' '.join(chunk for chunk in chunks if chunk)
-
- return text
- except Exception as e:
+ return markdown_text
+ except requests.exceptions.RequestException as e:
logger.error(f"Error downloading {url}: {e}")
return ""
+ except Exception as e:
+ logger.error(f"An unexpected error occurred: {e}")
+ return ""
def perform_web_search(query, num_pages=3, max_workers=5):
"""Perform web search and return results with content"""
+ from duckduckgo_search import DDGS
+
try:
with DDGS() as ddgs:
results = list(ddgs.text(query, max_results=num_pages))
diff --git a/requirements/full/requirements.txt b/requirements/full/requirements.txt
index 277f8249..b751482a 100644
--- a/requirements/full/requirements.txt
+++ b/requirements/full/requirements.txt
@@ -1,5 +1,4 @@
accelerate==1.5.*
-beautifulsoup4==4.13.4
bitsandbytes==0.45.*
colorama
datasets
@@ -7,6 +6,7 @@ duckduckgo_search==8.0.2
einops
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==1.26.*
diff --git a/requirements/full/requirements_amd.txt b/requirements/full/requirements_amd.txt
index dbf35c34..11bacf97 100644
--- a/requirements/full/requirements_amd.txt
+++ b/requirements/full/requirements_amd.txt
@@ -1,11 +1,11 @@
accelerate==1.5.*
-beautifulsoup4==4.13.4
colorama
datasets
duckduckgo_search==8.0.2
einops
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==1.26.*
diff --git a/requirements/full/requirements_amd_noavx2.txt b/requirements/full/requirements_amd_noavx2.txt
index 2e5eb6c9..a64a93f0 100644
--- a/requirements/full/requirements_amd_noavx2.txt
+++ b/requirements/full/requirements_amd_noavx2.txt
@@ -1,11 +1,11 @@
accelerate==1.5.*
-beautifulsoup4==4.13.4
colorama
datasets
duckduckgo_search==8.0.2
einops
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==1.26.*
diff --git a/requirements/full/requirements_apple_intel.txt b/requirements/full/requirements_apple_intel.txt
index 9a19ab29..62747ac4 100644
--- a/requirements/full/requirements_apple_intel.txt
+++ b/requirements/full/requirements_apple_intel.txt
@@ -1,11 +1,11 @@
accelerate==1.5.*
-beautifulsoup4==4.13.4
colorama
datasets
duckduckgo_search==8.0.2
einops
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==1.26.*
diff --git a/requirements/full/requirements_apple_silicon.txt b/requirements/full/requirements_apple_silicon.txt
index 973d9bfb..bc82f07a 100644
--- a/requirements/full/requirements_apple_silicon.txt
+++ b/requirements/full/requirements_apple_silicon.txt
@@ -1,11 +1,11 @@
accelerate==1.5.*
-beautifulsoup4==4.13.4
colorama
datasets
duckduckgo_search==8.0.2
einops
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==1.26.*
diff --git a/requirements/full/requirements_cpu_only.txt b/requirements/full/requirements_cpu_only.txt
index 4a48a51f..f880f40a 100644
--- a/requirements/full/requirements_cpu_only.txt
+++ b/requirements/full/requirements_cpu_only.txt
@@ -1,11 +1,11 @@
accelerate==1.5.*
-beautifulsoup4==4.13.4
colorama
datasets
duckduckgo_search==8.0.2
einops
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==1.26.*
diff --git a/requirements/full/requirements_cpu_only_noavx2.txt b/requirements/full/requirements_cpu_only_noavx2.txt
index 76bde864..6d8875cb 100644
--- a/requirements/full/requirements_cpu_only_noavx2.txt
+++ b/requirements/full/requirements_cpu_only_noavx2.txt
@@ -1,11 +1,11 @@
accelerate==1.5.*
-beautifulsoup4==4.13.4
colorama
datasets
duckduckgo_search==8.0.2
einops
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==1.26.*
diff --git a/requirements/full/requirements_cuda128.txt b/requirements/full/requirements_cuda128.txt
index 9fc99606..b2bcf91c 100644
--- a/requirements/full/requirements_cuda128.txt
+++ b/requirements/full/requirements_cuda128.txt
@@ -1,5 +1,4 @@
accelerate==1.5.*
-beautifulsoup4==4.13.4
bitsandbytes==0.45.*
colorama
datasets
@@ -7,6 +6,7 @@ duckduckgo_search==8.0.2
einops
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==2.2.*
diff --git a/requirements/full/requirements_cuda128_noavx2.txt b/requirements/full/requirements_cuda128_noavx2.txt
index ff34673a..54496cd7 100644
--- a/requirements/full/requirements_cuda128_noavx2.txt
+++ b/requirements/full/requirements_cuda128_noavx2.txt
@@ -1,5 +1,4 @@
accelerate==1.5.*
-beautifulsoup4==4.13.4
bitsandbytes==0.45.*
colorama
datasets
@@ -7,6 +6,7 @@ duckduckgo_search==8.0.2
einops
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==2.2.*
diff --git a/requirements/full/requirements_noavx2.txt b/requirements/full/requirements_noavx2.txt
index 6cd0fa65..eabcdbd0 100644
--- a/requirements/full/requirements_noavx2.txt
+++ b/requirements/full/requirements_noavx2.txt
@@ -1,5 +1,4 @@
accelerate==1.5.*
-beautifulsoup4==4.13.4
bitsandbytes==0.45.*
colorama
datasets
@@ -7,6 +6,7 @@ duckduckgo_search==8.0.2
einops
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==1.26.*
diff --git a/requirements/full/requirements_nowheels.txt b/requirements/full/requirements_nowheels.txt
index a412367c..d26663a7 100644
--- a/requirements/full/requirements_nowheels.txt
+++ b/requirements/full/requirements_nowheels.txt
@@ -1,11 +1,11 @@
accelerate==1.5.*
-beautifulsoup4==4.13.4
colorama
datasets
duckduckgo_search==8.0.2
einops
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==1.26.*
diff --git a/requirements/portable/requirements.txt b/requirements/portable/requirements.txt
index 60ce941e..5e5d4ba5 100644
--- a/requirements/portable/requirements.txt
+++ b/requirements/portable/requirements.txt
@@ -1,7 +1,7 @@
-beautifulsoup4==4.13.4
duckduckgo_search==8.0.2
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==1.26.*
diff --git a/requirements/portable/requirements_apple_intel.txt b/requirements/portable/requirements_apple_intel.txt
index b1649bc9..4909f5a2 100644
--- a/requirements/portable/requirements_apple_intel.txt
+++ b/requirements/portable/requirements_apple_intel.txt
@@ -1,7 +1,7 @@
-beautifulsoup4==4.13.4
duckduckgo_search==8.0.2
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==1.26.*
diff --git a/requirements/portable/requirements_apple_silicon.txt b/requirements/portable/requirements_apple_silicon.txt
index 571eba52..e54b2593 100644
--- a/requirements/portable/requirements_apple_silicon.txt
+++ b/requirements/portable/requirements_apple_silicon.txt
@@ -1,7 +1,7 @@
-beautifulsoup4==4.13.4
duckduckgo_search==8.0.2
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==1.26.*
diff --git a/requirements/portable/requirements_cpu_only.txt b/requirements/portable/requirements_cpu_only.txt
index 88170cf3..74c0c5a7 100644
--- a/requirements/portable/requirements_cpu_only.txt
+++ b/requirements/portable/requirements_cpu_only.txt
@@ -1,7 +1,7 @@
-beautifulsoup4==4.13.4
duckduckgo_search==8.0.2
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==1.26.*
diff --git a/requirements/portable/requirements_cpu_only_noavx2.txt b/requirements/portable/requirements_cpu_only_noavx2.txt
index e96cef49..264bc378 100644
--- a/requirements/portable/requirements_cpu_only_noavx2.txt
+++ b/requirements/portable/requirements_cpu_only_noavx2.txt
@@ -1,7 +1,7 @@
-beautifulsoup4==4.13.4
duckduckgo_search==8.0.2
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==1.26.*
diff --git a/requirements/portable/requirements_noavx2.txt b/requirements/portable/requirements_noavx2.txt
index 78f94aa5..fcb8f05e 100644
--- a/requirements/portable/requirements_noavx2.txt
+++ b/requirements/portable/requirements_noavx2.txt
@@ -1,7 +1,7 @@
-beautifulsoup4==4.13.4
duckduckgo_search==8.0.2
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==1.26.*
diff --git a/requirements/portable/requirements_nowheels.txt b/requirements/portable/requirements_nowheels.txt
index f6c866cf..3d30e6d6 100644
--- a/requirements/portable/requirements_nowheels.txt
+++ b/requirements/portable/requirements_nowheels.txt
@@ -1,7 +1,7 @@
-beautifulsoup4==4.13.4
duckduckgo_search==8.0.2
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==1.26.*
diff --git a/requirements/portable/requirements_vulkan.txt b/requirements/portable/requirements_vulkan.txt
index 3e41427d..395f225f 100644
--- a/requirements/portable/requirements_vulkan.txt
+++ b/requirements/portable/requirements_vulkan.txt
@@ -1,7 +1,7 @@
-beautifulsoup4==4.13.4
duckduckgo_search==8.0.2
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==1.26.*
diff --git a/requirements/portable/requirements_vulkan_noavx2.txt b/requirements/portable/requirements_vulkan_noavx2.txt
index 022ebb61..0d41f541 100644
--- a/requirements/portable/requirements_vulkan_noavx2.txt
+++ b/requirements/portable/requirements_vulkan_noavx2.txt
@@ -1,7 +1,7 @@
-beautifulsoup4==4.13.4
duckduckgo_search==8.0.2
fastapi==0.112.4
gradio==4.37.*
+html2text==2025.4.15
jinja2==3.1.6
markdown
numpy==1.26.*
From d085dc6a93577bbafbde529c497528965dbfc19b Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Mon, 9 Jun 2025 18:40:54 -0700
Subject: [PATCH 67/82] Minor optimization after
e976a5ddc7598de49227f600515a7eee72fc1af6
---
js/dark_theme.js | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/js/dark_theme.js b/js/dark_theme.js
index f61060cd..7136f5bf 100644
--- a/js/dark_theme.js
+++ b/js/dark_theme.js
@@ -9,8 +9,12 @@ function toggleDarkMode() {
// Re-highlight all code blocks once stylesheet loads
currentCSS.onload = function() {
- document.querySelectorAll("pre code").forEach(block => {
- hljs.highlightElement(block);
+ const messageBodies = document.getElementById("chat").querySelectorAll(".message-body");
+ messageBodies.forEach((messageBody) => {
+ const codeBlocks = messageBody.querySelectorAll("pre code");
+ codeBlocks.forEach((codeBlock) => {
+ hljs.highlightElement(codeBlock);
+ });
});
};
}
From 1443612e72619e063d57226d05df3c159ec6d0ca Mon Sep 17 00:00:00 2001
From: Miriam
Date: Mon, 9 Jun 2025 19:22:01 -0700
Subject: [PATCH 68/82] check .attention.head_count if .attention.head_count_kv
doesn't exist (#7048)
---
modules/models_settings.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/modules/models_settings.py b/modules/models_settings.py
index c914bdea..283a9744 100644
--- a/modules/models_settings.py
+++ b/modules/models_settings.py
@@ -329,6 +329,7 @@ def estimate_vram(gguf_file, gpu_layers, ctx_size, cache_type):
# Extract values from metadata
n_layers = None
n_kv_heads = None
+ n_attention_heads = None # Fallback for models without separate KV heads
embedding_dim = None
for key, value in metadata.items():
@@ -336,9 +337,14 @@ def estimate_vram(gguf_file, gpu_layers, ctx_size, cache_type):
n_layers = value
elif key.endswith('.attention.head_count_kv'):
n_kv_heads = max(value) if isinstance(value, list) else value
+ elif key.endswith('.attention.head_count'):
+ n_attention_heads = max(value) if isinstance(value, list) else value
elif key.endswith('.embedding_length'):
embedding_dim = value
+ if n_kv_heads is None:
+ n_kv_heads = n_attention_heads
+
if gpu_layers > n_layers:
gpu_layers = n_layers
From 331d03c33fd69dd50b5c3b9f9ed8fb7d9da56bf0 Mon Sep 17 00:00:00 2001
From: Miriam
Date: Mon, 9 Jun 2025 19:25:39 -0700
Subject: [PATCH 69/82] fix failure when --nowebui called without --api (#7055)
---
server.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/server.py b/server.py
index 5cad1d8a..80cc2f18 100644
--- a/server.py
+++ b/server.py
@@ -318,8 +318,8 @@ if __name__ == "__main__":
if shared.args.nowebui:
# Start the API in standalone mode
- shared.args.extensions = [x for x in shared.args.extensions if x != 'gallery']
- if shared.args.extensions is not None and len(shared.args.extensions) > 0:
+ shared.args.extensions = [x for x in (shared.args.extensions or []) if x != 'gallery']
+ if shared.args.extensions:
extensions_module.load_extensions()
else:
# Launch the web UI
From ec731210200ab53dc26bf56e6616d4533f64c165 Mon Sep 17 00:00:00 2001
From: Mykeehu
Date: Tue, 10 Jun 2025 05:17:05 +0200
Subject: [PATCH 70/82] Fix continue/start reply with when using translation
extensions (#6944)
---------
Co-authored-by: oobabooga
---
modules/chat.py | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/modules/chat.py b/modules/chat.py
index 25a0607b..88ba33bb 100644
--- a/modules/chat.py
+++ b/modules/chat.py
@@ -760,7 +760,18 @@ def chatbot_wrapper(text, state, regenerate=False, _continue=False, loading_mess
if is_stream:
yield output
- output['visible'][-1][1] = apply_extensions('output', output['visible'][-1][1], state, is_chat=True)
+ if _continue:
+ # Reprocess the entire internal text for extensions (like translation)
+ full_internal = output['internal'][-1][1]
+ if state['mode'] in ['chat', 'chat-instruct']:
+ full_visible = re.sub("(||{{user}})", state['name1'], full_internal)
+ else:
+ full_visible = full_internal
+
+ full_visible = html.escape(full_visible)
+ output['visible'][-1][1] = apply_extensions('output', full_visible, state, is_chat=True)
+ else:
+ output['visible'][-1][1] = apply_extensions('output', output['visible'][-1][1], state, is_chat=True)
# Final sync for version metadata (in case streaming was disabled)
if regenerate:
From df98f4b3312f84995d4dbdbe73681ed78c8e08d2 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Mon, 9 Jun 2025 20:28:16 -0700
Subject: [PATCH 71/82] Don't save active extensions through the UI
Prevents command-line activated extensions from becoming permanently active due to autosave.
---
modules/shared.py | 1 -
modules/ui.py | 1 -
server.py | 6 ------
3 files changed, 8 deletions(-)
diff --git a/modules/shared.py b/modules/shared.py
index 59c7dbcd..cc2884c1 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -224,7 +224,6 @@ settings = {
'negative_prompt': '',
'dark_theme': True,
'paste_to_attachment': False,
- 'default_extensions': [],
# Character settings
'character': 'Assistant',
diff --git a/modules/ui.py b/modules/ui.py
index 38693da8..ca1ff528 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -327,7 +327,6 @@ def save_settings(state, preset, extensions_list, show_controls, theme_state):
output['prompt-default'] = state['prompt_menu-default']
output['prompt-notebook'] = state['prompt_menu-notebook']
output['character'] = state['character_menu']
- output['default_extensions'] = extensions_list
output['seed'] = int(output['seed'])
output['show_controls'] = show_controls
output['dark_theme'] = True if theme_state == 'dark' else False
diff --git a/server.py b/server.py
index 80cc2f18..e0e3fbe5 100644
--- a/server.py
+++ b/server.py
@@ -249,13 +249,7 @@ if __name__ == "__main__":
shared.model_config['.*'] = get_fallback_settings()
shared.model_config.move_to_end('.*', last=False) # Move to the beginning
- # Activate the extensions listed on settings.yaml
extensions_module.available_extensions = utils.get_available_extensions()
- for extension in shared.settings['default_extensions']:
- shared.args.extensions = shared.args.extensions or []
- if extension not in shared.args.extensions:
- shared.args.extensions.append(extension)
-
available_models = utils.get_available_models()
# Model defined through --model
From efd9c9707b809754b2e467b53bbeb76688768e6d Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Mon, 9 Jun 2025 20:57:25 -0700
Subject: [PATCH 72/82] Fix random seeds being saved to settings.yaml
---
modules/text_generation.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/modules/text_generation.py b/modules/text_generation.py
index 0d499d50..55b538b0 100644
--- a/modules/text_generation.py
+++ b/modules/text_generation.py
@@ -479,6 +479,7 @@ def generate_reply_custom(question, original_question, state, stopping_strings=N
For models that do not use the transformers library for sampling
"""
+ state = copy.deepcopy(state)
state['seed'] = set_manual_seed(state['seed'])
t0 = time.time()
reply = ''
From c92eba0b0a0776119ce1912e25dbeeb7a1dfc749 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Mon, 9 Jun 2025 22:03:23 -0700
Subject: [PATCH 73/82] Reorganize the Parameters tab (left: preset parameters,
right: everything else)
---
modules/ui_parameters.py | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/modules/ui_parameters.py b/modules/ui_parameters.py
index 9b5cb3ab..e2b10554 100644
--- a/modules/ui_parameters.py
+++ b/modules/ui_parameters.py
@@ -34,6 +34,7 @@ def create_ui():
shared.gradio['dynatemp_exponent'] = gr.Slider(0.01, 5, value=shared.settings['dynatemp_exponent'], step=0.01, label='dynatemp_exponent', visible=shared.settings['dynamic_temperature'])
shared.gradio['smoothing_factor'] = gr.Slider(0.0, 10.0, value=shared.settings['smoothing_factor'], step=0.01, label='smoothing_factor', info='Activates Quadratic Sampling.')
shared.gradio['smoothing_curve'] = gr.Slider(1.0, 10.0, value=shared.settings['smoothing_curve'], step=0.01, label='smoothing_curve', info='Adjusts the dropoff curve of Quadratic Sampling.')
+ shared.gradio['dynamic_temperature'] = gr.Checkbox(value=shared.settings['dynamic_temperature'], label='dynamic_temperature')
gr.Markdown('## Curve cutoff')
shared.gradio['min_p'] = gr.Slider(0.0, 1.0, value=shared.settings['min_p'], step=0.01, label='min_p')
@@ -68,15 +69,19 @@ def create_ui():
shared.gradio['mirostat_eta'] = gr.Slider(0, 1, step=0.01, value=shared.settings['mirostat_eta'], label='mirostat_eta')
gr.Markdown('## Other options')
- shared.gradio['max_new_tokens'] = gr.Slider(minimum=shared.settings['max_new_tokens_min'], maximum=shared.settings['max_new_tokens_max'], value=shared.settings['max_new_tokens'], step=1, label='max_new_tokens', info='⚠️ Setting this too high can cause prompt truncation.')
- shared.gradio['prompt_lookup_num_tokens'] = gr.Slider(value=shared.settings['prompt_lookup_num_tokens'], minimum=0, maximum=10, step=1, label='prompt_lookup_num_tokens', info='Activates Prompt Lookup Decoding.')
- shared.gradio['max_tokens_second'] = gr.Slider(value=shared.settings['max_tokens_second'], minimum=0, maximum=20, step=1, label='Maximum tokens/second', info='To make text readable in real time.')
+ shared.gradio['do_sample'] = gr.Checkbox(value=shared.settings['do_sample'], label='do_sample')
+ shared.gradio['temperature_last'] = gr.Checkbox(value=shared.settings['temperature_last'], label='temperature_last', info='Moves temperature/dynamic temperature/quadratic sampling to the end of the sampler stack, ignoring their positions in "Sampler priority".')
+ shared.gradio['sampler_priority'] = gr.Textbox(value=shared.settings['sampler_priority'], lines=10, label='Sampler priority', info='Parameter names separated by new lines or commas.', elem_classes=['add_scrollbar'])
+ shared.gradio['dry_sequence_breakers'] = gr.Textbox(value=shared.settings['dry_sequence_breakers'], label='dry_sequence_breakers', info='Tokens across which sequence matching is not continued. Specified as a comma-separated list of quoted strings.')
+
with gr.Column():
with gr.Row():
with gr.Column():
- shared.gradio['do_sample'] = gr.Checkbox(value=shared.settings['do_sample'], label='do_sample')
- shared.gradio['dynamic_temperature'] = gr.Checkbox(value=shared.settings['dynamic_temperature'], label='dynamic_temperature')
- shared.gradio['temperature_last'] = gr.Checkbox(value=shared.settings['temperature_last'], label='temperature_last', info='Moves temperature/dynamic temperature/quadratic sampling to the end of the sampler stack, ignoring their positions in "Sampler priority".')
+ with gr.Blocks():
+ shared.gradio['max_new_tokens'] = gr.Slider(minimum=shared.settings['max_new_tokens_min'], maximum=shared.settings['max_new_tokens_max'], value=shared.settings['max_new_tokens'], step=1, label='max_new_tokens', info='⚠️ Setting this too high can cause prompt truncation.')
+ shared.gradio['prompt_lookup_num_tokens'] = gr.Slider(value=shared.settings['prompt_lookup_num_tokens'], minimum=0, maximum=10, step=1, label='prompt_lookup_num_tokens', info='Activates Prompt Lookup Decoding.')
+ shared.gradio['max_tokens_second'] = gr.Slider(value=shared.settings['max_tokens_second'], minimum=0, maximum=20, step=1, label='Maximum tokens/second', info='To make text readable in real time.')
+
shared.gradio['auto_max_new_tokens'] = gr.Checkbox(value=shared.settings['auto_max_new_tokens'], label='auto_max_new_tokens', info='Expand max_new_tokens to the available context length.')
shared.gradio['ban_eos_token'] = gr.Checkbox(value=shared.settings['ban_eos_token'], label='Ban the eos_token', info='Forces the model to never end the generation prematurely.')
shared.gradio['add_bos_token'] = gr.Checkbox(value=shared.settings['add_bos_token'], label='Add the bos_token to the beginning of prompts', info='Disabling this can make the replies more creative.')
@@ -89,11 +94,9 @@ def create_ui():
shared.gradio['truncation_length'] = gr.Number(precision=0, step=256, value=get_truncation_length(), label='Truncate the prompt up to this length', info='The leftmost tokens are removed if the prompt exceeds this length.')
shared.gradio['seed'] = gr.Number(value=shared.settings['seed'], label='Seed (-1 for random)')
- shared.gradio['sampler_priority'] = gr.Textbox(value=shared.settings['sampler_priority'], lines=12, label='Sampler priority', info='Parameter names separated by new lines or commas.', elem_classes=['add_scrollbar'])
shared.gradio['custom_stopping_strings'] = gr.Textbox(lines=2, value=shared.settings["custom_stopping_strings"] or None, label='Custom stopping strings', info='Written between "" and separated by commas.', placeholder='"\\n", "\\nYou:"')
shared.gradio['custom_token_bans'] = gr.Textbox(value=shared.settings['custom_token_bans'] or None, label='Token bans', info='Token IDs to ban, separated by commas. The IDs can be found in the Default or Notebook tab.')
shared.gradio['negative_prompt'] = gr.Textbox(value=shared.settings['negative_prompt'], label='Negative prompt', info='For CFG. Only used when guidance_scale is different than 1.', lines=3, elem_classes=['add_scrollbar'])
- shared.gradio['dry_sequence_breakers'] = gr.Textbox(value=shared.settings['dry_sequence_breakers'], label='dry_sequence_breakers', info='Tokens across which sequence matching is not continued. Specified as a comma-separated list of quoted strings.')
with gr.Row() as shared.gradio['grammar_file_row']:
shared.gradio['grammar_file'] = gr.Dropdown(value='None', choices=utils.get_available_grammars(), label='Load grammar from file (.gbnf)', elem_classes='slim-dropdown')
ui.create_refresh_button(shared.gradio['grammar_file'], lambda: None, lambda: {'choices': utils.get_available_grammars()}, 'refresh-button', interactive=not mu)
From 2dabdbc7da85f91ea9ddd74dfb49c2d161a6ef4d Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Tue, 10 Jun 2025 05:25:23 -0700
Subject: [PATCH 74/82] Update llama.cpp
---
requirements/full/requirements.txt | 4 ++--
requirements/full/requirements_amd.txt | 4 ++--
requirements/full/requirements_amd_noavx2.txt | 4 ++--
requirements/full/requirements_apple_intel.txt | 4 ++--
requirements/full/requirements_apple_silicon.txt | 6 +++---
requirements/full/requirements_cpu_only.txt | 4 ++--
requirements/full/requirements_cpu_only_noavx2.txt | 4 ++--
requirements/full/requirements_cuda128.txt | 4 ++--
requirements/full/requirements_cuda128_noavx2.txt | 4 ++--
requirements/full/requirements_noavx2.txt | 4 ++--
requirements/portable/requirements.txt | 4 ++--
requirements/portable/requirements_apple_intel.txt | 4 ++--
requirements/portable/requirements_apple_silicon.txt | 6 +++---
requirements/portable/requirements_cpu_only.txt | 4 ++--
requirements/portable/requirements_cpu_only_noavx2.txt | 4 ++--
requirements/portable/requirements_noavx2.txt | 4 ++--
requirements/portable/requirements_vulkan.txt | 4 ++--
requirements/portable/requirements_vulkan_noavx2.txt | 4 ++--
18 files changed, 38 insertions(+), 38 deletions(-)
diff --git a/requirements/full/requirements.txt b/requirements/full/requirements.txt
index b751482a..a71e5240 100644
--- a/requirements/full/requirements.txt
+++ b/requirements/full/requirements.txt
@@ -34,8 +34,8 @@ sse-starlette==1.6.5
tiktoken
# CUDA wheels
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cu124-py3-none-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cu124-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64" and python_version == "3.11"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cu124-py3-none-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cu124-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64" and python_version == "3.11"
https://github.com/oobabooga/exllamav3/releases/download/v0.0.3/exllamav3-0.0.3+cu124.torch2.6.0-cp311-cp311-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
https://github.com/oobabooga/exllamav3/releases/download/v0.0.3/exllamav3-0.0.3+cu124.torch2.6.0-cp311-cp311-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64" and python_version == "3.11"
https://github.com/turboderp-org/exllamav2/releases/download/v0.3.1/exllamav2-0.3.1+cu124.torch2.6.0-cp311-cp311-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
diff --git a/requirements/full/requirements_amd.txt b/requirements/full/requirements_amd.txt
index 11bacf97..db1ead1a 100644
--- a/requirements/full/requirements_amd.txt
+++ b/requirements/full/requirements_amd.txt
@@ -33,7 +33,7 @@ sse-starlette==1.6.5
tiktoken
# AMD wheels
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+vulkan-py3-none-win_amd64.whl; platform_system == "Windows"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+vulkan-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+vulkan-py3-none-win_amd64.whl; platform_system == "Windows"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+vulkan-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64"
https://github.com/turboderp-org/exllamav2/releases/download/v0.3.1/exllamav2-0.3.1+rocm6.2.4.torch2.6.0-cp311-cp311-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64" and python_version == "3.11"
https://github.com/turboderp-org/exllamav2/releases/download/v0.3.1/exllamav2-0.3.1-py3-none-any.whl; platform_system != "Darwin" and platform_machine != "x86_64"
diff --git a/requirements/full/requirements_amd_noavx2.txt b/requirements/full/requirements_amd_noavx2.txt
index a64a93f0..a08aa392 100644
--- a/requirements/full/requirements_amd_noavx2.txt
+++ b/requirements/full/requirements_amd_noavx2.txt
@@ -33,7 +33,7 @@ sse-starlette==1.6.5
tiktoken
# AMD wheels
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+vulkanavx-py3-none-win_amd64.whl; platform_system == "Windows"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+vulkanavx-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+vulkanavx-py3-none-win_amd64.whl; platform_system == "Windows"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+vulkanavx-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64"
https://github.com/turboderp-org/exllamav2/releases/download/v0.3.1/exllamav2-0.3.1+rocm6.2.4.torch2.6.0-cp311-cp311-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64" and python_version == "3.11"
https://github.com/turboderp-org/exllamav2/releases/download/v0.3.1/exllamav2-0.3.1-py3-none-any.whl; platform_system != "Darwin" and platform_machine != "x86_64"
diff --git a/requirements/full/requirements_apple_intel.txt b/requirements/full/requirements_apple_intel.txt
index 62747ac4..fa217c3e 100644
--- a/requirements/full/requirements_apple_intel.txt
+++ b/requirements/full/requirements_apple_intel.txt
@@ -33,7 +33,7 @@ sse-starlette==1.6.5
tiktoken
# Mac wheels
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0-py3-none-macosx_15_0_x86_64.whl; platform_system == "Darwin" and platform_release >= "24.0.0" and platform_release < "25.0.0" and python_version == "3.11"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0-py3-none-macosx_14_0_x86_64.whl; platform_system == "Darwin" and platform_release >= "23.0.0" and platform_release < "24.0.0" and python_version == "3.11"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0-py3-none-macosx_15_0_x86_64.whl; platform_system == "Darwin" and platform_release >= "24.0.0" and platform_release < "25.0.0" and python_version == "3.11"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0-py3-none-macosx_14_0_x86_64.whl; platform_system == "Darwin" and platform_release >= "23.0.0" and platform_release < "24.0.0" and python_version == "3.11"
https://github.com/oobabooga/exllamav3/releases/download/v0.0.3/exllamav3-0.0.3-py3-none-any.whl
https://github.com/turboderp-org/exllamav2/releases/download/v0.3.1/exllamav2-0.3.1-py3-none-any.whl
diff --git a/requirements/full/requirements_apple_silicon.txt b/requirements/full/requirements_apple_silicon.txt
index bc82f07a..52581f1a 100644
--- a/requirements/full/requirements_apple_silicon.txt
+++ b/requirements/full/requirements_apple_silicon.txt
@@ -33,8 +33,8 @@ sse-starlette==1.6.5
tiktoken
# Mac wheels
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0-py3-none-macosx_15_0_arm64.whl; platform_system == "Darwin" and platform_release >= "24.0.0" and platform_release < "25.0.0" and python_version == "3.11"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0-py3-none-macosx_14_0_arm64.whl; platform_system == "Darwin" and platform_release >= "23.0.0" and platform_release < "24.0.0" and python_version == "3.11"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0-py3-none-macosx_13_0_arm64.whl; platform_system == "Darwin" and platform_release >= "22.0.0" and platform_release < "23.0.0" and python_version == "3.11"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0-py3-none-macosx_15_0_arm64.whl; platform_system == "Darwin" and platform_release >= "24.0.0" and platform_release < "25.0.0" and python_version == "3.11"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0-py3-none-macosx_14_0_arm64.whl; platform_system == "Darwin" and platform_release >= "23.0.0" and platform_release < "24.0.0" and python_version == "3.11"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0-py3-none-macosx_13_0_arm64.whl; platform_system == "Darwin" and platform_release >= "22.0.0" and platform_release < "23.0.0" and python_version == "3.11"
https://github.com/oobabooga/exllamav3/releases/download/v0.0.3/exllamav3-0.0.3-py3-none-any.whl
https://github.com/turboderp-org/exllamav2/releases/download/v0.3.1/exllamav2-0.3.1-py3-none-any.whl
diff --git a/requirements/full/requirements_cpu_only.txt b/requirements/full/requirements_cpu_only.txt
index f880f40a..b72f22aa 100644
--- a/requirements/full/requirements_cpu_only.txt
+++ b/requirements/full/requirements_cpu_only.txt
@@ -33,5 +33,5 @@ sse-starlette==1.6.5
tiktoken
# llama.cpp (CPU only, AVX2)
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cpuavx2-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64" and python_version == "3.11"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cpuavx2-py3-none-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cpuavx2-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64" and python_version == "3.11"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cpuavx2-py3-none-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
diff --git a/requirements/full/requirements_cpu_only_noavx2.txt b/requirements/full/requirements_cpu_only_noavx2.txt
index 6d8875cb..e8de6057 100644
--- a/requirements/full/requirements_cpu_only_noavx2.txt
+++ b/requirements/full/requirements_cpu_only_noavx2.txt
@@ -33,5 +33,5 @@ sse-starlette==1.6.5
tiktoken
# llama.cpp (CPU only, no AVX2)
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cpuavx-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64" and python_version == "3.11"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cpuavx-py3-none-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cpuavx-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64" and python_version == "3.11"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cpuavx-py3-none-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
diff --git a/requirements/full/requirements_cuda128.txt b/requirements/full/requirements_cuda128.txt
index b2bcf91c..801009fb 100644
--- a/requirements/full/requirements_cuda128.txt
+++ b/requirements/full/requirements_cuda128.txt
@@ -35,8 +35,8 @@ sse-starlette==1.6.5
tiktoken
# CUDA wheels
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cu124-py3-none-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cu124-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64" and python_version == "3.11"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cu124-py3-none-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cu124-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64" and python_version == "3.11"
https://github.com/turboderp-org/exllamav3/releases/download/v0.0.3/exllamav3-0.0.3+cu128.torch2.7.0-cp311-cp311-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
https://github.com/turboderp-org/exllamav3/releases/download/v0.0.3/exllamav3-0.0.3+cu128.torch2.7.0-cp311-cp311-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64" and python_version == "3.11"
https://github.com/turboderp-org/exllamav2/releases/download/v0.3.1/exllamav2-0.3.1+cu128.torch2.7.0-cp311-cp311-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
diff --git a/requirements/full/requirements_cuda128_noavx2.txt b/requirements/full/requirements_cuda128_noavx2.txt
index 54496cd7..8b77e144 100644
--- a/requirements/full/requirements_cuda128_noavx2.txt
+++ b/requirements/full/requirements_cuda128_noavx2.txt
@@ -35,8 +35,8 @@ sse-starlette==1.6.5
tiktoken
# CUDA wheels
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cu124avx-py3-none-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cu124avx-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64" and python_version == "3.11"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cu124avx-py3-none-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cu124avx-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64" and python_version == "3.11"
https://github.com/turboderp-org/exllamav3/releases/download/v0.0.3/exllamav3-0.0.3+cu128.torch2.7.0-cp311-cp311-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
https://github.com/turboderp-org/exllamav3/releases/download/v0.0.3/exllamav3-0.0.3+cu128.torch2.7.0-cp311-cp311-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64" and python_version == "3.11"
https://github.com/turboderp-org/exllamav2/releases/download/v0.3.1/exllamav2-0.3.1+cu128.torch2.7.0-cp311-cp311-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
diff --git a/requirements/full/requirements_noavx2.txt b/requirements/full/requirements_noavx2.txt
index eabcdbd0..5e81ce1f 100644
--- a/requirements/full/requirements_noavx2.txt
+++ b/requirements/full/requirements_noavx2.txt
@@ -34,8 +34,8 @@ sse-starlette==1.6.5
tiktoken
# CUDA wheels
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cu124avx-py3-none-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cu124avx-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64" and python_version == "3.11"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cu124avx-py3-none-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cu124avx-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64" and python_version == "3.11"
https://github.com/oobabooga/exllamav3/releases/download/v0.0.3/exllamav3-0.0.3+cu124.torch2.6.0-cp311-cp311-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
https://github.com/oobabooga/exllamav3/releases/download/v0.0.3/exllamav3-0.0.3+cu124.torch2.6.0-cp311-cp311-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64" and python_version == "3.11"
https://github.com/turboderp-org/exllamav2/releases/download/v0.3.1/exllamav2-0.3.1+cu124.torch2.6.0-cp311-cp311-win_amd64.whl; platform_system == "Windows" and python_version == "3.11"
diff --git a/requirements/portable/requirements.txt b/requirements/portable/requirements.txt
index 5e5d4ba5..4ddcf43f 100644
--- a/requirements/portable/requirements.txt
+++ b/requirements/portable/requirements.txt
@@ -19,5 +19,5 @@ sse-starlette==1.6.5
tiktoken
# CUDA wheels
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cu124-py3-none-win_amd64.whl; platform_system == "Windows"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cu124-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cu124-py3-none-win_amd64.whl; platform_system == "Windows"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cu124-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64"
diff --git a/requirements/portable/requirements_apple_intel.txt b/requirements/portable/requirements_apple_intel.txt
index 4909f5a2..38a21618 100644
--- a/requirements/portable/requirements_apple_intel.txt
+++ b/requirements/portable/requirements_apple_intel.txt
@@ -19,5 +19,5 @@ sse-starlette==1.6.5
tiktoken
# Mac wheels
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0-py3-none-macosx_15_0_x86_64.whl; platform_system == "Darwin" and platform_release >= "24.0.0" and platform_release < "25.0.0"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0-py3-none-macosx_14_0_x86_64.whl; platform_system == "Darwin" and platform_release >= "23.0.0" and platform_release < "24.0.0"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0-py3-none-macosx_15_0_x86_64.whl; platform_system == "Darwin" and platform_release >= "24.0.0" and platform_release < "25.0.0"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0-py3-none-macosx_14_0_x86_64.whl; platform_system == "Darwin" and platform_release >= "23.0.0" and platform_release < "24.0.0"
diff --git a/requirements/portable/requirements_apple_silicon.txt b/requirements/portable/requirements_apple_silicon.txt
index e54b2593..0b70c800 100644
--- a/requirements/portable/requirements_apple_silicon.txt
+++ b/requirements/portable/requirements_apple_silicon.txt
@@ -19,6 +19,6 @@ sse-starlette==1.6.5
tiktoken
# Mac wheels
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0-py3-none-macosx_15_0_arm64.whl; platform_system == "Darwin" and platform_release >= "24.0.0" and platform_release < "25.0.0"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0-py3-none-macosx_14_0_arm64.whl; platform_system == "Darwin" and platform_release >= "23.0.0" and platform_release < "24.0.0"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0-py3-none-macosx_13_0_arm64.whl; platform_system == "Darwin" and platform_release >= "22.0.0" and platform_release < "23.0.0"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0-py3-none-macosx_15_0_arm64.whl; platform_system == "Darwin" and platform_release >= "24.0.0" and platform_release < "25.0.0"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0-py3-none-macosx_14_0_arm64.whl; platform_system == "Darwin" and platform_release >= "23.0.0" and platform_release < "24.0.0"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0-py3-none-macosx_13_0_arm64.whl; platform_system == "Darwin" and platform_release >= "22.0.0" and platform_release < "23.0.0"
diff --git a/requirements/portable/requirements_cpu_only.txt b/requirements/portable/requirements_cpu_only.txt
index 74c0c5a7..510a20f4 100644
--- a/requirements/portable/requirements_cpu_only.txt
+++ b/requirements/portable/requirements_cpu_only.txt
@@ -19,5 +19,5 @@ sse-starlette==1.6.5
tiktoken
# llama.cpp (CPU only, AVX2)
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cpuavx2-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cpuavx2-py3-none-win_amd64.whl; platform_system == "Windows"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cpuavx2-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cpuavx2-py3-none-win_amd64.whl; platform_system == "Windows"
diff --git a/requirements/portable/requirements_cpu_only_noavx2.txt b/requirements/portable/requirements_cpu_only_noavx2.txt
index 264bc378..e6d9f0c5 100644
--- a/requirements/portable/requirements_cpu_only_noavx2.txt
+++ b/requirements/portable/requirements_cpu_only_noavx2.txt
@@ -19,5 +19,5 @@ sse-starlette==1.6.5
tiktoken
# llama.cpp (CPU only, no AVX2)
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cpuavx-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cpuavx-py3-none-win_amd64.whl; platform_system == "Windows"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cpuavx-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cpuavx-py3-none-win_amd64.whl; platform_system == "Windows"
diff --git a/requirements/portable/requirements_noavx2.txt b/requirements/portable/requirements_noavx2.txt
index fcb8f05e..48f92e0a 100644
--- a/requirements/portable/requirements_noavx2.txt
+++ b/requirements/portable/requirements_noavx2.txt
@@ -19,5 +19,5 @@ sse-starlette==1.6.5
tiktoken
# CUDA wheels
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cu124avx-py3-none-win_amd64.whl; platform_system == "Windows"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+cu124avx-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cu124avx-py3-none-win_amd64.whl; platform_system == "Windows"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+cu124avx-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64"
diff --git a/requirements/portable/requirements_vulkan.txt b/requirements/portable/requirements_vulkan.txt
index 395f225f..9f93424f 100644
--- a/requirements/portable/requirements_vulkan.txt
+++ b/requirements/portable/requirements_vulkan.txt
@@ -19,5 +19,5 @@ sse-starlette==1.6.5
tiktoken
# CUDA wheels
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+vulkan-py3-none-win_amd64.whl; platform_system == "Windows"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+vulkan-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+vulkan-py3-none-win_amd64.whl; platform_system == "Windows"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+vulkan-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64"
diff --git a/requirements/portable/requirements_vulkan_noavx2.txt b/requirements/portable/requirements_vulkan_noavx2.txt
index 0d41f541..9070b9a6 100644
--- a/requirements/portable/requirements_vulkan_noavx2.txt
+++ b/requirements/portable/requirements_vulkan_noavx2.txt
@@ -19,5 +19,5 @@ sse-starlette==1.6.5
tiktoken
# CUDA wheels
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+vulkanavx-py3-none-win_amd64.whl; platform_system == "Windows"
-https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.16.0/llama_cpp_binaries-0.16.0+vulkanavx-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+vulkanavx-py3-none-win_amd64.whl; platform_system == "Windows"
+https://github.com/oobabooga/llama-cpp-binaries/releases/download/v0.18.0/llama_cpp_binaries-0.18.0+vulkanavx-py3-none-linux_x86_64.whl; platform_system == "Linux" and platform_machine == "x86_64"
From 889153952f5545fb2b94b7a853aa24ae754ef79f Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Tue, 10 Jun 2025 09:02:52 -0700
Subject: [PATCH 75/82] Lint
---
modules/ui_model_menu.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/modules/ui_model_menu.py b/modules/ui_model_menu.py
index 2a7d3d9d..9e982f0e 100644
--- a/modules/ui_model_menu.py
+++ b/modules/ui_model_menu.py
@@ -260,6 +260,7 @@ def download_model_wrapper(repo_id, specific_file, progress=gr.Progress(), retur
output = "```\n"
for link in links:
output += f"{Path(link).name}" + "\n"
+
output += "```"
yield output
return
From 18bd78f1f038b2b69178d464184b937f7d2b15d6 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Tue, 10 Jun 2025 14:03:25 -0700
Subject: [PATCH 76/82] Make the llama.cpp prompt processing messages shorter
---
modules/llama_cpp_server.py | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/modules/llama_cpp_server.py b/modules/llama_cpp_server.py
index f0a72de8..a79e24e4 100644
--- a/modules/llama_cpp_server.py
+++ b/modules/llama_cpp_server.py
@@ -422,9 +422,17 @@ def filter_stderr_with_progress(process_stderr):
if match:
progress = float(match.group(1))
+
+ # Extract just the part from "prompt processing" onwards
+ prompt_processing_idx = line.find('prompt processing')
+ if prompt_processing_idx != -1:
+ display_line = line[prompt_processing_idx:]
+ else:
+ display_line = line # fallback to full line
+
# choose carriage return for in-progress or newline at completion
end_char = '\r' if progress < 1.0 else '\n'
- print(line, end=end_char, file=sys.stderr, flush=True)
+ print(display_line, end=end_char, file=sys.stderr, flush=True)
last_was_progress = (progress < 1.0)
# skip noise lines
From 3f9eb3aad1d1a734791dd41e4817570d81b485eb Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Tue, 10 Jun 2025 14:22:37 -0700
Subject: [PATCH 77/82] Fix the preset dropdown when the default preset file is
not present
---
modules/shared.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/shared.py b/modules/shared.py
index cc2884c1..b8ab2426 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -204,7 +204,7 @@ settings = {
'web_search_pages': 3,
'prompt-default': 'QA',
'prompt-notebook': 'QA',
- 'preset': 'Qwen3 - Thinking' if Path('user_data/presets/Qwen3 - Thinking.yaml').exists() else '',
+ 'preset': 'Qwen3 - Thinking' if Path('user_data/presets/Qwen3 - Thinking.yaml').exists() else None,
'max_new_tokens': 512,
'max_new_tokens_min': 1,
'max_new_tokens_max': 4096,
From 1c1fd3be46f66b2f3110aed52a155817ca3392b7 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Tue, 10 Jun 2025 14:29:28 -0700
Subject: [PATCH 78/82] Remove some log messages
---
modules/chat.py | 5 -----
1 file changed, 5 deletions(-)
diff --git a/modules/chat.py b/modules/chat.py
index 88ba33bb..dfc301df 100644
--- a/modules/chat.py
+++ b/modules/chat.py
@@ -1271,8 +1271,6 @@ def clear_character_for_ui(state):
if cache_path.exists():
cache_path.unlink()
- logger.info("Cleared character fields and picture cache")
-
return state, state['name2'], state['context'], state['greeting'], None
@@ -1779,7 +1777,6 @@ def handle_character_picture_change(picture):
picture.save(Path(f'{cache_folder}/pfp_character.png'), format='PNG')
thumb = make_thumbnail(picture)
thumb.save(Path(f'{cache_folder}/pfp_character_thumb.png'), format='PNG')
- logger.info("Updated character picture cache")
else:
# Remove cache files when picture is cleared
for cache_file in ['pfp_character.png', 'pfp_character_thumb.png']:
@@ -1787,8 +1784,6 @@ def handle_character_picture_change(picture):
if cache_path.exists():
cache_path.unlink()
- logger.info("Cleared character picture cache")
-
def handle_mode_change(state):
history = load_latest_history(state)
From 75da90190f33317dd9731e14d844dd7238a2c870 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Tue, 10 Jun 2025 17:34:54 -0700
Subject: [PATCH 79/82] Fix character dropdown sometimes disappearing in the
Parameters tab
---
modules/ui_chat.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/ui_chat.py b/modules/ui_chat.py
index 428b64c9..3b841b8b 100644
--- a/modules/ui_chat.py
+++ b/modules/ui_chat.py
@@ -298,7 +298,7 @@ def create_event_handlers():
shared.gradio['mode'].change(
ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
chat.handle_mode_change, gradio('interface_state'), gradio('history', 'display', 'chat_style', 'chat-instruct_command', 'unique_id'), show_progress=False).then(
- None, gradio('mode'), None, js="(mode) => {mode === 'instruct' ? document.getElementById('character-menu').parentNode.parentNode.style.display = 'none' : document.getElementById('character-menu').parentNode.parentNode.style.display = ''}")
+ None, gradio('mode'), None, js="(mode) => {const characterContainer = document.getElementById('character-menu').parentNode.parentNode; const isInChatTab = document.querySelector('#chat-controls').contains(characterContainer); if (isInChatTab) { characterContainer.style.display = mode === 'instruct' ? 'none' : ''; }}")
shared.gradio['chat_style'].change(chat.redraw_html, gradio(reload_arr), gradio('display'), show_progress=False)
From 4cf39120fca88fc78aeaaa55946ab74e5db1a512 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Tue, 10 Jun 2025 18:03:00 -0700
Subject: [PATCH 80/82] Fix chat area sometimes not scrolling up to edit
message
---
js/global_scope_js.js | 9 +++++++++
js/main.js | 8 ++++----
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/js/global_scope_js.js b/js/global_scope_js.js
index 801f1574..205d9375 100644
--- a/js/global_scope_js.js
+++ b/js/global_scope_js.js
@@ -95,12 +95,21 @@ function startEditing(messageElement, messageBody, isUserMessage) {
editingInterface.textarea.focus();
editingInterface.textarea.setSelectionRange(rawText.length, rawText.length);
+ // Temporarily mark as scrolled to prevent auto-scroll
+ const wasScrolled = window.isScrolled;
+ window.isScrolled = true;
+
// Scroll the textarea into view
editingInterface.textarea.scrollIntoView({
behavior: "smooth",
block: "center"
});
+ // Restore the original scroll state after animation
+ setTimeout(() => {
+ window.isScrolled = wasScrolled;
+ }, 500);
+
// Setup event handlers
setupEditingHandlers(editingInterface.textarea, messageElement, originalHTML, messageBody, isUserMessage);
}
diff --git a/js/main.js b/js/main.js
index 1953a6be..e970884d 100644
--- a/js/main.js
+++ b/js/main.js
@@ -145,7 +145,7 @@ typingSibling.insertBefore(typing, typingSibling.childNodes[2]);
const targetElement = document.getElementById("chat").parentNode.parentNode.parentNode;
targetElement.classList.add("pretty_scrollbar");
targetElement.classList.add("chat-parent");
-let isScrolled = false;
+window.isScrolled = false;
let scrollTimeout;
targetElement.addEventListener("scroll", function() {
@@ -154,9 +154,9 @@ targetElement.addEventListener("scroll", function() {
let diff = targetElement.scrollHeight - targetElement.clientHeight;
if(Math.abs(targetElement.scrollTop - diff) <= 10 || diff == 0) {
- isScrolled = false;
+ window.isScrolled = false;
} else {
- isScrolled = true;
+ window.isScrolled = true;
}
// Clear previous timeout and set new one
@@ -182,7 +182,7 @@ const observer = new MutationObserver(function(mutations) {
doSyntaxHighlighting();
- if (!isScrolled && targetElement.scrollTop !== targetElement.scrollHeight) {
+ if (!window.isScrolled && targetElement.scrollTop !== targetElement.scrollHeight) {
targetElement.scrollTop = targetElement.scrollHeight;
}
From bc921c66e5ef2f2a14286702e564c1b22dbba5a7 Mon Sep 17 00:00:00 2001
From: LawnMauer
Date: Wed, 11 Jun 2025 03:16:50 +0200
Subject: [PATCH 81/82] Load js and css sources in UTF-8 (#7059)
---
modules/html_generator.py | 7 ++++---
modules/ui.py | 22 +++++++++++-----------
2 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/modules/html_generator.py b/modules/html_generator.py
index eac7d91a..af64894e 100644
--- a/modules/html_generator.py
+++ b/modules/html_generator.py
@@ -39,15 +39,16 @@ def minify_css(css: str) -> str:
return css
-with open(Path(__file__).resolve().parent / '../css/html_readable_style.css', 'r') as f:
+with open(Path(__file__).resolve().parent / '../css/html_readable_style.css', 'r', encoding='utf-8') as f:
readable_css = f.read()
-with open(Path(__file__).resolve().parent / '../css/html_instruct_style.css', 'r') as f:
+with open(Path(__file__).resolve().parent / '../css/html_instruct_style.css', 'r', encoding='utf-8') as f:
instruct_css = f.read()
# Custom chat styles
chat_styles = {}
for k in get_available_chat_styles():
- chat_styles[k] = open(Path(f'css/chat_style-{k}.css'), 'r').read()
+ with open(Path(f'css/chat_style-{k}.css'), 'r', encoding='utf-8') as f:
+ chat_styles[k] = f.read()
# Handle styles that derive from other styles
for k in chat_styles:
diff --git a/modules/ui.py b/modules/ui.py
index ca1ff528..59da5118 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -19,27 +19,27 @@ _last_extensions = None
_last_show_controls = None
_last_theme_state = None
-with open(Path(__file__).resolve().parent / '../css/NotoSans/stylesheet.css', 'r') as f:
+with open(Path(__file__).resolve().parent / '../css/NotoSans/stylesheet.css', 'r', encoding='utf-8') as f:
css = f.read()
-with open(Path(__file__).resolve().parent / '../css/main.css', 'r') as f:
+with open(Path(__file__).resolve().parent / '../css/main.css', 'r', encoding='utf-8') as f:
css += f.read()
-with open(Path(__file__).resolve().parent / '../css/katex/katex.min.css', 'r') as f:
+with open(Path(__file__).resolve().parent / '../css/katex/katex.min.css', 'r', encoding='utf-8') as f:
css += f.read()
-with open(Path(__file__).resolve().parent / '../css/highlightjs/highlightjs-copy.min.css', 'r') as f:
+with open(Path(__file__).resolve().parent / '../css/highlightjs/highlightjs-copy.min.css', 'r', encoding='utf-8') as f:
css += f.read()
-with open(Path(__file__).resolve().parent / '../js/main.js', 'r') as f:
+with open(Path(__file__).resolve().parent / '../js/main.js', 'r', encoding='utf-8') as f:
js = f.read()
-with open(Path(__file__).resolve().parent / '../js/global_scope_js.js', 'r') as f:
+with open(Path(__file__).resolve().parent / '../js/global_scope_js.js', 'r', encoding='utf-8') as f:
global_scope_js = f.read()
-with open(Path(__file__).resolve().parent / '../js/save_files.js', 'r') as f:
+with open(Path(__file__).resolve().parent / '../js/save_files.js', 'r', encoding='utf-8') as f:
save_files_js = f.read()
-with open(Path(__file__).resolve().parent / '../js/switch_tabs.js', 'r') as f:
+with open(Path(__file__).resolve().parent / '../js/switch_tabs.js', 'r', encoding='utf-8') as f:
switch_tabs_js = f.read()
-with open(Path(__file__).resolve().parent / '../js/show_controls.js', 'r') as f:
+with open(Path(__file__).resolve().parent / '../js/show_controls.js', 'r', encoding='utf-8') as f:
show_controls_js = f.read()
-with open(Path(__file__).resolve().parent / '../js/update_big_picture.js', 'r') as f:
+with open(Path(__file__).resolve().parent / '../js/update_big_picture.js', 'r', encoding='utf-8') as f:
update_big_picture_js = f.read()
-with open(Path(__file__).resolve().parent / '../js/dark_theme.js', 'r') as f:
+with open(Path(__file__).resolve().parent / '../js/dark_theme.js', 'r', encoding='utf-8') as f:
dark_theme_js = f.read()
refresh_symbol = '🔄'
From 552cb09f09de0d3a9442334580fd4a66f95a1ce3 Mon Sep 17 00:00:00 2001
From: oobabooga <112222186+oobabooga@users.noreply.github.com>
Date: Tue, 10 Jun 2025 18:45:42 -0700
Subject: [PATCH 82/82] Do not bump Transformers to 4.52 on CUDA 12.8
Performance is slow, and the older version works fine with torch 2.7.
---
requirements/full/requirements_cuda128.txt | 3 +--
requirements/full/requirements_cuda128_noavx2.txt | 3 +--
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/requirements/full/requirements_cuda128.txt b/requirements/full/requirements_cuda128.txt
index 801009fb..7851041f 100644
--- a/requirements/full/requirements_cuda128.txt
+++ b/requirements/full/requirements_cuda128.txt
@@ -24,8 +24,7 @@ safetensors==0.5.*
scipy
sentencepiece
tensorboard
-transformers==4.52.*
-triton-windows; platform_system == "Windows"
+transformers==4.50.*
tqdm
wandb
diff --git a/requirements/full/requirements_cuda128_noavx2.txt b/requirements/full/requirements_cuda128_noavx2.txt
index 8b77e144..c8015166 100644
--- a/requirements/full/requirements_cuda128_noavx2.txt
+++ b/requirements/full/requirements_cuda128_noavx2.txt
@@ -24,8 +24,7 @@ safetensors==0.5.*
scipy
sentencepiece
tensorboard
-transformers==4.52.*
-triton-windows; platform_system == "Windows"
+transformers==4.50.*
tqdm
wandb