Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -2,6 +2,7 @@ import gradio as gr
|
|
2 |
import requests
|
3 |
import json
|
4 |
import os
|
|
|
5 |
from datetime import datetime
|
6 |
|
7 |
|
@@ -27,10 +28,33 @@ def get_ai_response(message, history):
|
|
27 |
try:
|
28 |
response = requests.post(API_ENDPOINT, headers=headers, json=payload)
|
29 |
response.raise_for_status()
|
30 |
-
|
|
|
|
|
|
|
|
|
31 |
except Exception as e:
|
32 |
return f"Error: {str(e)}"
|
33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
def chat_interface(message, history, stored_history):
|
35 |
"""Handle chat interactions and update history."""
|
36 |
if not history:
|
@@ -39,8 +63,12 @@ def chat_interface(message, history, stored_history):
|
|
39 |
# Convert history to the format expected by the API
|
40 |
api_history = []
|
41 |
for user_msg, ai_msg in history:
|
|
|
|
|
|
|
|
|
42 |
api_history.append({"role": "user", "content": user_msg})
|
43 |
-
api_history.append({"role": "assistant", "content":
|
44 |
|
45 |
ai_response = get_ai_response(message, api_history)
|
46 |
|
@@ -50,10 +78,15 @@ def chat_interface(message, history, stored_history):
|
|
50 |
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
51 |
if stored_history is None:
|
52 |
stored_history = []
|
|
|
|
|
|
|
|
|
|
|
53 |
stored_history.insert(0, {
|
54 |
"timestamp": timestamp,
|
55 |
"user": message,
|
56 |
-
"ai":
|
57 |
})
|
58 |
return history, stored_history
|
59 |
|
@@ -67,8 +100,8 @@ def update_history_display(stored_history):
|
|
67 |
html += f"""
|
68 |
<li class='history-item'>
|
69 |
<small>{item['timestamp']}</small><br>
|
70 |
-
<strong>You:</strong> {item['user'][:50]}
|
71 |
-
<strong>AI:</strong> {item['ai'][:50]}...
|
72 |
</li>
|
73 |
"""
|
74 |
html += "</ul>"
|
@@ -91,10 +124,24 @@ body { background-color: #1a1a1a; color: #ffffff; font-family: 'Arial', sans-ser
|
|
91 |
.history-item:hover { background-color: #404040; }
|
92 |
input, button { background-color: #333333; color: #ffffff; border: 1px solid #404040; border-radius: 5px; }
|
93 |
button:hover { background-color: #404040; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
"""
|
95 |
|
96 |
# Build the Gradio app
|
97 |
-
with gr.Blocks(css=custom_css, title="
|
98 |
with gr.Row():
|
99 |
# Sidebar for history
|
100 |
with gr.Column(scale=1, min_width=300, elem_id="sidebar"):
|
@@ -104,7 +151,9 @@ with gr.Blocks(css=custom_css, title="Reka Flash 3 Demo") as demo:
|
|
104 |
|
105 |
# Main chat area
|
106 |
with gr.Column(scale=3):
|
107 |
-
|
|
|
|
|
108 |
with gr.Row():
|
109 |
message = gr.Textbox(placeholder="Type your message...", show_label=False, container=False)
|
110 |
submit_btn = gr.Button("Send", size="sm")
|
@@ -121,6 +170,35 @@ with gr.Blocks(css=custom_css, title="Reka Flash 3 Demo") as demo:
|
|
121 |
return history ? JSON.parse(history) : [];
|
122 |
}
|
123 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
|
125 |
# Event handlers
|
126 |
submit_btn.click(
|
@@ -141,6 +219,25 @@ with gr.Blocks(css=custom_css, title="Reka Flash 3 Demo") as demo:
|
|
141 |
message
|
142 |
)
|
143 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
clear_chat_btn.click(
|
145 |
lambda: ([], None),
|
146 |
None,
|
@@ -167,6 +264,11 @@ with gr.Blocks(css=custom_css, title="Reka Flash 3 Demo") as demo:
|
|
167 |
update_history_display,
|
168 |
history_state,
|
169 |
history_display
|
|
|
|
|
|
|
|
|
|
|
170 |
)
|
171 |
|
172 |
demo.launch()
|
|
|
2 |
import requests
|
3 |
import json
|
4 |
import os
|
5 |
+
import re
|
6 |
from datetime import datetime
|
7 |
|
8 |
|
|
|
28 |
try:
|
29 |
response = requests.post(API_ENDPOINT, headers=headers, json=payload)
|
30 |
response.raise_for_status()
|
31 |
+
raw_response = response.json()["choices"][0]["message"]["content"]
|
32 |
+
|
33 |
+
# Convert reasoning tags to collapsible HTML
|
34 |
+
html_response = convert_reasoning_to_collapsible(raw_response)
|
35 |
+
return html_response
|
36 |
except Exception as e:
|
37 |
return f"Error: {str(e)}"
|
38 |
|
39 |
+
def convert_reasoning_to_collapsible(text):
|
40 |
+
"""Convert reasoning tags to collapsible HTML sections."""
|
41 |
+
# Find all reasoning sections
|
42 |
+
reasoning_pattern = re.compile(r'<reasoning>(.*?)</reasoning>', re.DOTALL)
|
43 |
+
|
44 |
+
# Function to replace each reasoning section with collapsible HTML
|
45 |
+
def replace_with_collapsible(match):
|
46 |
+
reasoning_content = match.group(1).strip()
|
47 |
+
return f'<details><summary><strong>See reasoning</strong></summary><div class="reasoning-content">{reasoning_content}</div></details>'
|
48 |
+
|
49 |
+
# Replace reasoning tags with collapsible sections
|
50 |
+
html_response = reasoning_pattern.sub(replace_with_collapsible, text)
|
51 |
+
|
52 |
+
# Remove <sep> tags
|
53 |
+
html_response = re.sub(r'<sep>.*?</sep>', '', html_response, flags=re.DOTALL)
|
54 |
+
html_response = html_response.replace('<sep>', '').replace('</sep>', '')
|
55 |
+
|
56 |
+
return html_response
|
57 |
+
|
58 |
def chat_interface(message, history, stored_history):
|
59 |
"""Handle chat interactions and update history."""
|
60 |
if not history:
|
|
|
63 |
# Convert history to the format expected by the API
|
64 |
api_history = []
|
65 |
for user_msg, ai_msg in history:
|
66 |
+
# Remove HTML tags for API history
|
67 |
+
clean_ai_msg = re.sub(r'<details>.*?</details>', '', ai_msg, flags=re.DOTALL)
|
68 |
+
clean_ai_msg = re.sub(r'<[^>]*>', '', clean_ai_msg)
|
69 |
+
|
70 |
api_history.append({"role": "user", "content": user_msg})
|
71 |
+
api_history.append({"role": "assistant", "content": clean_ai_msg})
|
72 |
|
73 |
ai_response = get_ai_response(message, api_history)
|
74 |
|
|
|
78 |
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
79 |
if stored_history is None:
|
80 |
stored_history = []
|
81 |
+
|
82 |
+
# Store a plain text version for history display
|
83 |
+
plain_response = re.sub(r'<details>.*?</details>', '[Reasoning available]', ai_response, flags=re.DOTALL)
|
84 |
+
plain_response = re.sub(r'<[^>]*>', '', plain_response)
|
85 |
+
|
86 |
stored_history.insert(0, {
|
87 |
"timestamp": timestamp,
|
88 |
"user": message,
|
89 |
+
"ai": plain_response
|
90 |
})
|
91 |
return history, stored_history
|
92 |
|
|
|
100 |
html += f"""
|
101 |
<li class='history-item'>
|
102 |
<small>{item['timestamp']}</small><br>
|
103 |
+
<strong>You:</strong> {item['user'][:50]}{'...' if len(item['user']) > 50 else ''}<br>
|
104 |
+
<strong>AI:</strong> {item['ai'][:50]}{'...' if len(item['ai']) > 50 else ''}
|
105 |
</li>
|
106 |
"""
|
107 |
html += "</ul>"
|
|
|
124 |
.history-item:hover { background-color: #404040; }
|
125 |
input, button { background-color: #333333; color: #ffffff; border: 1px solid #404040; border-radius: 5px; }
|
126 |
button:hover { background-color: #404040; }
|
127 |
+
details { background-color: #333333; padding: 10px; margin: 5px 0; border-radius: 5px; }
|
128 |
+
summary { cursor: pointer; color: #70a9e6; }
|
129 |
+
.reasoning-content { padding: 10px; margin-top: 5px; background-color: #404040; border-radius: 5px; }
|
130 |
+
"""
|
131 |
+
|
132 |
+
# HTML head for rendering HTML in chatbot
|
133 |
+
html_head = """
|
134 |
+
<head>
|
135 |
+
<style>
|
136 |
+
details { background-color: #333333; padding: 10px; margin: 5px 0; border-radius: 5px; }
|
137 |
+
summary { cursor: pointer; color: #70a9e6; }
|
138 |
+
.reasoning-content { padding: 10px; margin-top: 5px; background-color: #404040; border-radius: 5px; }
|
139 |
+
</style>
|
140 |
+
</head>
|
141 |
"""
|
142 |
|
143 |
# Build the Gradio app
|
144 |
+
with gr.Blocks(css=custom_css, title="AI Assistant with Collapsible Reasoning") as demo:
|
145 |
with gr.Row():
|
146 |
# Sidebar for history
|
147 |
with gr.Column(scale=1, min_width=300, elem_id="sidebar"):
|
|
|
151 |
|
152 |
# Main chat area
|
153 |
with gr.Column(scale=3):
|
154 |
+
gr.Markdown("## AI Assistant")
|
155 |
+
gr.Markdown("This assistant shows reasoning in collapsible sections.")
|
156 |
+
chatbot = gr.Chatbot(elem_id="chatbot", render_markdown=False, bubble_full_width=True)
|
157 |
with gr.Row():
|
158 |
message = gr.Textbox(placeholder="Type your message...", show_label=False, container=False)
|
159 |
submit_btn = gr.Button("Send", size="sm")
|
|
|
170 |
return history ? JSON.parse(history) : [];
|
171 |
}
|
172 |
"""
|
173 |
+
|
174 |
+
# JavaScript for enabling HTML in chatbot
|
175 |
+
js = """
|
176 |
+
function() {
|
177 |
+
// Add event listener for when new messages are added
|
178 |
+
const observer = new MutationObserver(function(mutations) {
|
179 |
+
mutations.forEach(function(mutation) {
|
180 |
+
if (mutation.addedNodes.length) {
|
181 |
+
document.querySelectorAll('#chatbot .message:not(.processed)').forEach(msg => {
|
182 |
+
msg.classList.add('processed');
|
183 |
+
// Replace content with innerHTML to render HTML
|
184 |
+
const content = msg.querySelector('.content');
|
185 |
+
if (content) {
|
186 |
+
content.innerHTML = content.textContent;
|
187 |
+
}
|
188 |
+
});
|
189 |
+
}
|
190 |
+
});
|
191 |
+
});
|
192 |
+
|
193 |
+
// Start observing chatbot for changes
|
194 |
+
const chatbot = document.getElementById('chatbot');
|
195 |
+
if (chatbot) {
|
196 |
+
observer.observe(chatbot, { childList: true, subtree: true });
|
197 |
+
}
|
198 |
+
|
199 |
+
return [];
|
200 |
+
}
|
201 |
+
"""
|
202 |
|
203 |
# Event handlers
|
204 |
submit_btn.click(
|
|
|
219 |
message
|
220 |
)
|
221 |
|
222 |
+
# Message submit via Enter key
|
223 |
+
message.submit(
|
224 |
+
chat_interface,
|
225 |
+
[message, chat_state, history_state],
|
226 |
+
[chat_state, history_state]
|
227 |
+
).then(
|
228 |
+
lambda history: history,
|
229 |
+
chat_state,
|
230 |
+
chatbot
|
231 |
+
).then(
|
232 |
+
update_history_display,
|
233 |
+
history_state,
|
234 |
+
history_display
|
235 |
+
).then(
|
236 |
+
lambda: "", # Clear the input box
|
237 |
+
None,
|
238 |
+
message
|
239 |
+
)
|
240 |
+
|
241 |
clear_chat_btn.click(
|
242 |
lambda: ([], None),
|
243 |
None,
|
|
|
264 |
update_history_display,
|
265 |
history_state,
|
266 |
history_display
|
267 |
+
).then(
|
268 |
+
fn=load_history_from_storage,
|
269 |
+
inputs=None,
|
270 |
+
outputs=None,
|
271 |
+
js=js
|
272 |
)
|
273 |
|
274 |
demo.launch()
|