Spaces:
Running
Running
| | |
| # ./app.py | |
| """ | |
| The Interface Skeleton - The code sets up the navigation panel and the multimodal chat interface | |
| The .then() chain: Previously, the save happened "in the background." Now, handle_save explicitly returns the new load_history() results to the history_list component, causing it to "re-render" with the new chat visible. | |
| The chat_id_state: By passing this back and forth, the app knows if it should update an existing file in the HF Dataset or create a new one. | |
| history_list.click: This is the bridge that makes the sidebar interactive. Without this event, clicking the "Recent Conversations" wouldn't do anything. | |
| """ | |
| import gradio as gr | |
| from core_logic import chat_function | |
| from storage import save_chat, load_history, get_chat_content | |
| with gr.Blocks() as demo: | |
| # This state keeps track of the filename for the current session | |
| chat_id_state = gr.State("") | |
| with gr.Row(): | |
| # --- Sidebar --- | |
| with gr.Column(scale=1, variant="secondary"): | |
| gr.Markdown("### 🛠️ Silicon Architect") | |
| new_btn = gr.Button("➕ New Chat", variant="primary") | |
| # The sidebar component | |
| history_list = gr.Dataset( | |
| components=[gr.Textbox(visible=False)], | |
| label="Recent Conversations", | |
| samples=load_history(), | |
| type="values" # Ensures we get the string value when clicked | |
| ) | |
| # --- Main Chat --- | |
| with gr.Column(scale=4): | |
| chatbot = gr.Chatbot(show_label=False, height=700) | |
| chat_input = gr.MultimodalTextbox( | |
| interactive=True, | |
| placeholder="Discuss architecture or upload code...", | |
| show_label=False | |
| ) | |
| # --- LOGIC FUNCTIONS --- | |
| def bot_response(message, history, chat_id): | |
| user_content = message["text"] | |
| history.append({"role": "user", "content": user_content}) | |
| history.append({"role": "assistant", "content": ""}) | |
| for partial_resp in chat_function(message, history[:-1]): | |
| history[-1]["content"] = partial_resp | |
| yield history | |
| """ | |
| def handle_save(history, chat_id): | |
| # Saves the chat and returns the updated list for the sidebar | |
| new_id = save_chat(chat_id, history) | |
| return new_id, load_history() | |
| """ | |
| def handle_save(history, chat_id): | |
| # 1. Save the actual data | |
| new_id = save_chat(chat_id, history) | |
| # 2. Get the latest from hub | |
| current_list = load_history() | |
| # 3. Ensure the current one is definitely at the top | |
| if [new_id] not in current_list: | |
| current_list.insert(0, [new_id]) | |
| return new_id, gr.update(samples=current_list) | |
| def load_past_chat(selected_list): | |
| # selected_list comes as [ 'chat_id' ] | |
| chat_id = selected_list[0] | |
| content = get_chat_content(chat_id) | |
| return content, chat_id | |
| # --- EVENT HANDLERS --- | |
| # 1. Submit Chat -> Stream Response -> Save -> Refresh Sidebar | |
| chat_input.submit( | |
| bot_response, | |
| [chat_input, chatbot, chat_id_state], | |
| [chatbot] | |
| ).then( | |
| handle_save, | |
| [chatbot, chat_id_state], | |
| [chat_id_state, history_list] | |
| ) | |
| # 2. Click Sidebar Item -> Load Content | |
| history_list.click( | |
| load_past_chat, | |
| [history_list], | |
| [chatbot, chat_id_state] | |
| ) | |
| # 3. New Chat Button | |
| new_btn.click( | |
| lambda: ([], "", load_history()), | |
| None, | |
| [chatbot, chat_id_state, history_list] | |
| ) | |
| # 4. "Force Refresh" | |
| # In Gradio, a component's samples are often cached at the moment of the initial load. To ensure the sidebar is truly dynamic, we need to update the gr.Dataset definition and the refresh logic | |
| # To update history_list definition, we add samples_per_page explicitly, ensuring it's not cutting off the list early | |
| history_list = gr.Dataset( | |
| components=[gr.Textbox(visible=False)], | |
| label="Recent Conversations", | |
| samples=load_history(), | |
| type="values", | |
| samples_per_page=20 # Increase this to see more at once | |
| ) | |
| demo.launch(theme=gr.themes.Soft(), css="styles.css") |