File size: 4,261 Bytes
f54201d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

# ./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")