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 |
+
]
|