UI: Add an incognito chat option

This commit is contained in:
oobabooga 2026-03-15 17:51:42 -07:00
parent 4f80b20859
commit c0de1d176c
4 changed files with 121 additions and 13 deletions

View file

@ -1022,6 +1022,49 @@ audio {
padding-right: 0.5rem;
}
#new-chat-wrapper {
display: contents;
}
.new-chat-arrow {
cursor: pointer;
position: relative;
padding: 0;
margin-right: -15px;
height: 39.594px;
display: flex;
align-items: center;
}
.new-chat-menu {
display: none;
position: absolute;
top: 0;
left: 0;
padding-top: 1.2em;
z-index: var(--layer-top);
white-space: nowrap;
}
.new-chat-arrow:hover .new-chat-menu {
display: block;
}
.new-chat-menu-item {
cursor: pointer;
padding: var(--size-2);
background: var(--background-fill-primary);
box-shadow: var(--shadow-drop-lg);
border-radius: var(--container-radius);
color: var(--body-text-color);
font-size: var(--text-md);
font-weight: var(--button-large-text-weight);
}
.new-chat-menu-item:hover {
background: var(--background-fill-secondary);
}
#past-chats-row,
#chat-controls {
width: 260px;

View file

@ -552,6 +552,38 @@ document.querySelectorAll(".focus-on-chat-input").forEach(element => {
});
});
//------------------------------------------------
// "New chat" hover menu with incognito option
//------------------------------------------------
(function() {
const newChatBtn = document.getElementById("new-chat-btn");
const wrapper = document.createElement("div");
wrapper.id = "new-chat-wrapper";
newChatBtn.replaceWith(wrapper);
wrapper.appendChild(newChatBtn);
const arrow = document.createElement("span");
arrow.className = "new-chat-arrow";
arrow.textContent = "\u25BE";
const menu = document.createElement("div");
menu.className = "new-chat-menu";
const option = document.createElement("div");
option.className = "new-chat-menu-item";
option.textContent = "Incognito chat";
menu.appendChild(option);
arrow.appendChild(menu);
wrapper.appendChild(arrow);
option.addEventListener("click", function(e) {
e.stopPropagation();
document.querySelector("#incognito-chat-btn").click();
});
})();
//------------------------------------------------
// Fix a border around the "past chats" menu
//------------------------------------------------

View file

@ -1528,7 +1528,7 @@ def redraw_html(history, name1, name2, mode, style, character, reset_cache=False
return chat_html_wrapper(history, name1, name2, mode, style, character, reset_cache=reset_cache)
def start_new_chat(state):
def start_new_chat(state, unique_id=None):
mode = state['mode']
# Initialize with empty metadata dictionary
history = {'internal': [], 'visible': [], 'metadata': {}}
@ -1542,7 +1542,9 @@ def start_new_chat(state):
# Add timestamp for assistant's greeting
update_message_metadata(history['metadata'], "assistant", 0, timestamp=get_current_timestamp())
unique_id = datetime.now().strftime('%Y%m%d-%H-%M-%S')
if unique_id is None:
unique_id = datetime.now().strftime('%Y%m%d-%H-%M-%S')
save_history(history, unique_id, state['character_menu'], state['mode'])
return history
@ -1561,6 +1563,9 @@ def save_history(history, unique_id, character, mode):
if shared.args.multi_user:
return
if unique_id and unique_id.startswith('incognito-'):
return
p = get_history_file_path(unique_id, character, mode)
if not p.parent.is_dir():
p.parent.mkdir(parents=True)
@ -1750,6 +1755,9 @@ def save_last_chat_state(character, mode, unique_id):
if shared.args.multi_user:
return
if unique_id and unique_id.startswith('incognito-'):
return
state = load_last_chat_state()
key = get_chat_state_key(character, mode)
state["last_chats"][key] = unique_id
@ -2290,11 +2298,29 @@ def handle_start_new_chat_click(state):
return [history, html, past_chats_update]
def handle_delete_chat_confirm_click(state):
def handle_start_incognito_chat_click(state):
import gradio as gr
unique_id = 'incognito-' + datetime.now().strftime('%Y%m%d-%H-%M-%S')
history = start_new_chat(state, unique_id=unique_id)
html = redraw_html(history, state['name1'], state['name2'], state['mode'], state['chat_style'], state['character_menu'])
convert_to_markdown.cache_clear()
histories = find_all_histories_with_first_prompts(state)
past_chats_update = gr.update(choices=histories, value=unique_id)
return [history, html, past_chats_update]
def handle_delete_chat_confirm_click(state):
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']))
if state['unique_id'] not in filtered_ids:
# Incognito or unknown chat — just load the most recent saved chat
index = '0'
else:
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)
@ -2302,13 +2328,7 @@ def handle_delete_chat_confirm_click(state):
convert_to_markdown.cache_clear()
return [
history,
html,
unique_id,
gr.update(visible=False),
gr.update(visible=True),
]
return [history, html, unique_id]
def handle_branch_chat_click(state):
@ -2324,7 +2344,8 @@ def handle_branch_chat_click(state):
if 'metadata' in history:
history['metadata'] = {k: v for k, v in history['metadata'].items() if int(k.split('_')[-1]) <= branch_from_index}
new_unique_id = datetime.now().strftime('%Y%m%d-%H-%M-%S')
prefix = 'incognito-' if state['unique_id'] and state['unique_id'].startswith('incognito-') else ''
new_unique_id = prefix + datetime.now().strftime('%Y%m%d-%H-%M-%S')
save_history(history, new_unique_id, state['character_menu'], state['mode'])
histories = find_all_histories_with_first_prompts(state)
@ -2446,6 +2467,13 @@ def handle_rename_chat_click():
def handle_rename_chat_confirm(rename_to, state):
import gradio as gr
if state['unique_id'] and state['unique_id'].startswith('incognito-'):
return [
gr.update(),
gr.update(visible=False),
]
rename_history(state['unique_id'], rename_to, state['character_menu'], state['mode'])
histories = find_all_histories_with_first_prompts(state)

View file

@ -28,7 +28,8 @@ def create_ui():
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('🗑️', 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['Start new chat'] = gr.Button('New chat', elem_classes=['refresh-button', 'refresh-button-medium', 'focus-on-chat-input'], elem_id='new-chat-btn')
shared.gradio['Start incognito chat'] = gr.Button('Incognito chat', visible=False, elem_id='incognito-chat-btn')
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')
@ -290,6 +291,10 @@ 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['Start incognito chat'].click(
ui.gather_interface_values, gradio(shared.input_elements), gradio('interface_state')).then(
chat.handle_start_incognito_chat_click, gradio('interface_state'), gradio('history', 'display', 'unique_id'), show_progress=False)
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'), show_progress=False)