Add conversation tracking with JSON export
Browse files- Added conversation viewer UI with JSON download capability
- Created test conversations for demonstration
- Fixed issue where conversations.json wasn't being created in Space
- Added public directory for better accessibility
- Users can now download conversation history directly from the UI
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
- app.py +43 -7
- conversation_tracker.py +21 -1
- conversations.json +27 -0
- public/conversations.json +27 -0
app.py
CHANGED
@@ -1130,18 +1130,54 @@ with gr.Blocks(css=custom_css, theme="soft", title="Trek Asistanı", head=storag
|
|
1130 |
|
1131 |
msg.submit(respond, [msg, chatbot], [msg, chatbot], show_progress=True)
|
1132 |
|
1133 |
-
# Add
|
1134 |
-
with gr.
|
1135 |
-
|
1136 |
-
|
|
|
|
|
|
|
|
|
|
|
1137 |
|
1138 |
def get_conversations_json():
|
1139 |
from conversation_tracker import load_conversations
|
1140 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1141 |
|
1142 |
-
refresh_btn.click(get_conversations_json, outputs=json_output)
|
1143 |
# Auto-load on start
|
1144 |
-
demo.load(get_conversations_json, outputs=
|
1145 |
|
1146 |
# API endpoints for dashboard
|
1147 |
def get_all_conversations():
|
|
|
1130 |
|
1131 |
msg.submit(respond, [msg, chatbot], [msg, chatbot], show_progress=True)
|
1132 |
|
1133 |
+
# Add conversation viewer
|
1134 |
+
with gr.Accordion("📊 Konuşma Geçmişi (JSON)", open=False):
|
1135 |
+
with gr.Row():
|
1136 |
+
refresh_json_btn = gr.Button("🔄 Yenile", scale=1)
|
1137 |
+
download_json_btn = gr.Button("💾 JSON İndir", scale=1)
|
1138 |
+
view_dashboard_btn = gr.Button("📈 Dashboard'u Aç", scale=1)
|
1139 |
+
|
1140 |
+
json_display = gr.JSON(label="Konuşmalar", elem_id="json_viewer")
|
1141 |
+
download_file = gr.File(label="İndir", visible=False)
|
1142 |
|
1143 |
def get_conversations_json():
|
1144 |
from conversation_tracker import load_conversations
|
1145 |
+
convs = load_conversations()
|
1146 |
+
# Also save to file for download
|
1147 |
+
import json as json_module
|
1148 |
+
with open("temp_conversations.json", "w", encoding="utf-8") as f:
|
1149 |
+
json_module.dump(convs, f, ensure_ascii=False, indent=2)
|
1150 |
+
return convs
|
1151 |
+
|
1152 |
+
def download_conversations():
|
1153 |
+
get_conversations_json() # Ensure file is updated
|
1154 |
+
return gr.update(visible=True, value="temp_conversations.json")
|
1155 |
+
|
1156 |
+
def open_dashboard():
|
1157 |
+
return gr.HTML("""
|
1158 |
+
<div style='padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 10px; color: white;'>
|
1159 |
+
<h3>📊 Dashboard Kullanım Talimatları</h3>
|
1160 |
+
<ol style='margin: 15px 0;'>
|
1161 |
+
<li>Yukarıdaki "💾 JSON İndir" butonuna tıkla</li>
|
1162 |
+
<li>conversations.json dosyasını indir</li>
|
1163 |
+
<li>bf_dashboard_json.html dosyasını aç</li>
|
1164 |
+
<li>İndirdiğin JSON dosyasını dashboard'a yükle</li>
|
1165 |
+
</ol>
|
1166 |
+
<p style='margin-top: 15px; font-size: 14px;'>
|
1167 |
+
Dashboard HTML dosyasını almak için:<br>
|
1168 |
+
<a href='https://github.com/yourusername/bf-dashboard' target='_blank' style='color: white; text-decoration: underline;'>
|
1169 |
+
GitHub'dan indir
|
1170 |
+
</a>
|
1171 |
+
</p>
|
1172 |
+
</div>
|
1173 |
+
""")
|
1174 |
+
|
1175 |
+
refresh_json_btn.click(get_conversations_json, outputs=json_display)
|
1176 |
+
download_json_btn.click(download_conversations, outputs=download_file)
|
1177 |
+
view_dashboard_btn.click(open_dashboard, outputs=json_display)
|
1178 |
|
|
|
1179 |
# Auto-load on start
|
1180 |
+
demo.load(get_conversations_json, outputs=json_display)
|
1181 |
|
1182 |
# API endpoints for dashboard
|
1183 |
def get_all_conversations():
|
conversation_tracker.py
CHANGED
@@ -26,10 +26,30 @@ def save_conversations(conversations):
|
|
26 |
if len(conversations) > MAX_CONVERSATIONS:
|
27 |
conversations = conversations[-MAX_CONVERSATIONS:]
|
28 |
|
|
|
29 |
with open(CONVERSATIONS_FILE, 'w', encoding='utf-8') as f:
|
30 |
json.dump(conversations, f, ensure_ascii=False, indent=2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
except Exception as e:
|
32 |
-
print(f"Error saving conversations: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
|
34 |
def add_conversation(user_message, bot_response):
|
35 |
"""Add a new conversation to history"""
|
|
|
26 |
if len(conversations) > MAX_CONVERSATIONS:
|
27 |
conversations = conversations[-MAX_CONVERSATIONS:]
|
28 |
|
29 |
+
# Try to save to file
|
30 |
with open(CONVERSATIONS_FILE, 'w', encoding='utf-8') as f:
|
31 |
json.dump(conversations, f, ensure_ascii=False, indent=2)
|
32 |
+
print(f"✅ Saved {len(conversations)} conversations to {CONVERSATIONS_FILE}")
|
33 |
+
|
34 |
+
# Also save to a backup location that Gradio can access
|
35 |
+
try:
|
36 |
+
import os
|
37 |
+
# Create a directory if it doesn't exist
|
38 |
+
os.makedirs("public", exist_ok=True)
|
39 |
+
with open("public/conversations.json", 'w', encoding='utf-8') as f:
|
40 |
+
json.dump(conversations, f, ensure_ascii=False, indent=2)
|
41 |
+
print("✅ Also saved to public/conversations.json")
|
42 |
+
except:
|
43 |
+
pass
|
44 |
+
|
45 |
except Exception as e:
|
46 |
+
print(f"❌ Error saving conversations: {e}")
|
47 |
+
# If file write fails, at least keep in memory
|
48 |
+
global _memory_conversations
|
49 |
+
_memory_conversations = conversations
|
50 |
+
|
51 |
+
# Keep a memory backup
|
52 |
+
_memory_conversations = []
|
53 |
|
54 |
def add_conversation(user_message, bot_response):
|
55 |
"""Add a new conversation to history"""
|
conversations.json
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
{
|
3 |
+
"timestamp": "2025-08-26T21:27:39.525318",
|
4 |
+
"user": "Madone SL 6 var mı?",
|
5 |
+
"bot": "Evet, MADONE SL 6 GEN 8 mevcut: Fiyat: 300.000 TL"
|
6 |
+
},
|
7 |
+
{
|
8 |
+
"timestamp": "2025-08-26T21:28:12.372071",
|
9 |
+
"user": "Marlin 7 hakkında bilgi ver",
|
10 |
+
"bot": "MARLIN 7 GEN 3 (2026) bisikletimiz: Fiyat: 87.000 TL"
|
11 |
+
},
|
12 |
+
{
|
13 |
+
"timestamp": "2025-08-26T21:28:12.372317",
|
14 |
+
"user": "En ucuz bisikletiniz hangisi?",
|
15 |
+
"bot": "En uygun fiyatlı modellerimiz: MARLIN 4: 41.000 TL"
|
16 |
+
},
|
17 |
+
{
|
18 |
+
"timestamp": "2025-08-26T21:28:12.373187",
|
19 |
+
"user": "Caddebostan da hangi bisikletler var?",
|
20 |
+
"bot": "Caddebostan mağazamızda: MADONE SL 6, MARLIN 7, DOMANE SL 5"
|
21 |
+
},
|
22 |
+
{
|
23 |
+
"timestamp": "2025-08-26T21:28:12.373783",
|
24 |
+
"user": "DOMANE SL 5 fiyatı nedir?",
|
25 |
+
"bot": "DOMANE SL 5 GEN 4: Fiyat: 210.000 TL"
|
26 |
+
}
|
27 |
+
]
|
public/conversations.json
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
{
|
3 |
+
"timestamp": "2025-08-26T21:27:39.525318",
|
4 |
+
"user": "Madone SL 6 var mı?",
|
5 |
+
"bot": "Evet, MADONE SL 6 GEN 8 mevcut: Fiyat: 300.000 TL"
|
6 |
+
},
|
7 |
+
{
|
8 |
+
"timestamp": "2025-08-26T21:28:12.372071",
|
9 |
+
"user": "Marlin 7 hakkında bilgi ver",
|
10 |
+
"bot": "MARLIN 7 GEN 3 (2026) bisikletimiz: Fiyat: 87.000 TL"
|
11 |
+
},
|
12 |
+
{
|
13 |
+
"timestamp": "2025-08-26T21:28:12.372317",
|
14 |
+
"user": "En ucuz bisikletiniz hangisi?",
|
15 |
+
"bot": "En uygun fiyatlı modellerimiz: MARLIN 4: 41.000 TL"
|
16 |
+
},
|
17 |
+
{
|
18 |
+
"timestamp": "2025-08-26T21:28:12.373187",
|
19 |
+
"user": "Caddebostan da hangi bisikletler var?",
|
20 |
+
"bot": "Caddebostan mağazamızda: MADONE SL 6, MARLIN 7, DOMANE SL 5"
|
21 |
+
},
|
22 |
+
{
|
23 |
+
"timestamp": "2025-08-26T21:28:12.373783",
|
24 |
+
"user": "DOMANE SL 5 fiyatı nedir?",
|
25 |
+
"bot": "DOMANE SL 5 GEN 4: Fiyat: 210.000 TL"
|
26 |
+
}
|
27 |
+
]
|