deven367 commited on
Commit
8abf36a
Β·
1 Parent(s): 4fb1986

working app

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +155 -38
src/streamlit_app.py CHANGED
@@ -1,40 +1,157 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
5
 
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from datetime import datetime
3
+
4
  import streamlit as st
5
 
6
+ # Set page config
7
+ st.set_page_config(page_title="Conversation Viewer", layout="wide")
8
+
9
+ @st.cache_data
10
+ def load_conversations(file_path):
11
+ """Load conversations from JSON file"""
12
+ with open(file_path, 'r', encoding='utf-8') as f:
13
+ return json.load(f)
14
+
15
+ def format_timestamp(timestamp):
16
+ """Convert timestamp to readable format"""
17
+ try:
18
+ if timestamp > 1e12: # milliseconds
19
+ timestamp = timestamp / 1000
20
+ return datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')
21
+ except:
22
+ return "N/A"
23
+
24
+ def search_in_conversation(conv, search_term):
25
+ """Check if search term exists in conversation"""
26
+ if not search_term:
27
+ return True
28
+
29
+ search_term = search_term.lower()
30
+
31
+ # Search in conversation name
32
+ if search_term in conv['conv']['name'].lower():
33
+ return True
34
+
35
+ # Search in messages
36
+ for msg in conv['messages']:
37
+ if 'content' in msg and search_term in msg['content'].lower():
38
+ return True
39
+
40
+ return False
41
+
42
+ def display_message(msg):
43
+ """Display a single message"""
44
+ if msg['role'] == 'user':
45
+ with st.chat_message("user"):
46
+ st.markdown(msg['content'])
47
+ elif msg['role'] == 'assistant':
48
+ with st.chat_message("assistant"):
49
+ # Remove <think> tags if present
50
+ content = msg['content']
51
+ if '<think>' in content and '</think>' in content:
52
+ start = content.find('<think>')
53
+ end = content.find('</think>') + len('</think>')
54
+ content = content[:start] + content[end:]
55
+ st.markdown(content)
56
+
57
+ def main():
58
+ st.title("πŸ’¬ Conversation Viewer")
59
+
60
+ # File selector
61
+ json_file = st.text_input(
62
+ "JSON File Path",
63
+ value="conversations_2025-11-01.json",
64
+ help="Enter the path to your conversations JSON file"
65
+ )
66
+
67
+
68
+
69
+ try:
70
+ conversations = load_conversations(json_file)
71
+
72
+ # Sidebar for search and filtering
73
+ with st.sidebar:
74
+ st.header("Search & Filter")
75
+ search_term = st.text_input("πŸ” Search conversations", "")
76
+
77
+ st.divider()
78
+
79
+ # Filter conversations
80
+ filtered_convs = [
81
+ conv for conv in conversations
82
+ if search_in_conversation(conv, search_term)
83
+ ]
84
+
85
+ st.write(f"**{len(filtered_convs)}** conversations found")
86
+
87
+ # Sort options
88
+ sort_by = st.selectbox(
89
+ "Sort by",
90
+ ["Most Recent", "Oldest First", "Alphabetical"]
91
+ )
92
+
93
+ if sort_by == "Most Recent":
94
+ filtered_convs.sort(key=lambda x: x['conv'].get('lastModified', 0), reverse=True)
95
+ elif sort_by == "Oldest First":
96
+ filtered_convs.sort(key=lambda x: x['conv'].get('lastModified', 0))
97
+ else:
98
+ filtered_convs.sort(key=lambda x: x['conv']['name'])
99
+
100
+ st.divider()
101
+
102
+ # Conversation list
103
+ st.subheader("Conversations")
104
+ selected_conv_id = st.radio(
105
+ "Select a conversation",
106
+ options=[conv['conv']['id'] for conv in filtered_convs],
107
+ format_func=lambda x: next(
108
+ (conv['conv']['name'][:50] + "..." if len(conv['conv']['name']) > 50
109
+ else conv['conv']['name'])
110
+ for conv in filtered_convs if conv['conv']['id'] == x
111
+ ),
112
+ label_visibility="collapsed"
113
+ )
114
+
115
+ # Main content area
116
+ if filtered_convs:
117
+ # Find selected conversation
118
+ selected_conv = next(
119
+ (conv for conv in filtered_convs if conv['conv']['id'] == selected_conv_id),
120
+ filtered_convs[0]
121
+ )
122
+
123
+ # Display conversation details
124
+ # have a border around this box
125
+ st.markdown(f"<div style='border: 1px solid #eee; padding: 10px; border-radius: 5px;'>", unsafe_allow_html=True)
126
+ st.write(selected_conv['conv']['name'])
127
+
128
+ col1, col2, col3 = st.columns(3)
129
+ with col1:
130
+ st.metric("Messages", len(selected_conv['messages']) - 1) # Exclude root
131
+ with col2:
132
+ st.metric("Last Modified", format_timestamp(selected_conv['conv']['lastModified']))
133
+ with col3:
134
+ st.metric("Conv ID", selected_conv['conv']['id'][:8] + "...")
135
+
136
+ st.divider()
137
+
138
+ # Display messages
139
+ messages = [msg for msg in selected_conv['messages'] if msg['role'] != 'root']
140
+
141
+ for msg in messages:
142
+ if msg['role'] in ['user', 'assistant']:
143
+ display_message(msg)
144
+ else:
145
+ st.info("No conversations found matching your search.")
146
+
147
+ except FileNotFoundError:
148
+ st.error(f"❌ File not found: {json_file}")
149
+ st.info("Please make sure the file path is correct.")
150
+ except json.JSONDecodeError:
151
+ st.error("❌ Invalid JSON file")
152
+ except Exception as e:
153
+ st.error(f"❌ Error: {str(e)}")
154
+
155
+ if __name__ == "__main__":
156
+ main()
157
+