uumerrr684 commited on
Commit
1a54d61
·
verified ·
1 Parent(s): 96bf65d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +145 -78
app.py CHANGED
@@ -1,221 +1,288 @@
1
- import streamlit as st
2
  import requests
3
  import os
4
  import json
 
5
 
6
- # Page config
7
  st.set_page_config(
8
  page_title="AI Assistant",
9
  page_icon="💬",
10
- layout="centered",
11
  initial_sidebar_state="collapsed"
12
  )
13
 
14
- # Enhanced styling with fixed transparent input
15
  st.markdown("""
16
  <style>
 
 
 
 
17
  .stApp {
18
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
19
- font-family: -apple-system, BlinkMacSystemFont, sans-serif;
 
20
  }
21
 
22
- /* Hide Streamlit elements */
23
- #MainMenu, footer, header { visibility: hidden; }
24
- .stDeployButton { display: none; }
 
 
 
 
 
 
 
 
 
25
 
26
- /* Clean header */
27
  .main-title {
28
  text-align: center;
29
  font-size: 2.5rem;
30
  font-weight: 600;
31
  color: #2d3748;
32
  margin-bottom: 0.5rem;
 
33
  }
34
 
35
  .main-subtitle {
36
- text-align: center;
37
  font-size: 1.1rem;
38
  color: #718096;
39
  margin-bottom: 3rem;
 
40
  }
41
 
 
42
  .welcome-message {
43
  text-align: center;
44
  font-size: 1.2rem;
45
  color: #4a5568;
46
  margin: 4rem 0;
 
 
 
 
 
 
 
 
 
47
  }
48
 
49
- /* User messages - Right aligned, blue */
50
  .stChatMessage[data-testid*="user"] {
51
  flex-direction: row-reverse !important;
52
  margin-left: 15% !important;
 
53
  }
54
 
55
  .stChatMessage[data-testid*="user"] .stMarkdown {
56
- background: #0066cc !important;
57
- color: white !important;
58
  border-radius: 18px 18px 4px 18px !important;
59
  padding: 12px 16px !important;
60
  margin-left: 12px !important;
 
61
  }
62
 
63
- /* AI messages - Left aligned, gray */
64
  .stChatMessage[data-testid*="assistant"] {
65
  margin-right: 15% !important;
 
66
  }
67
 
68
  .stChatMessage[data-testid*="assistant"] .stMarkdown {
69
- background: #f8f9fa !important;
70
- color: #2d3748 !important;
71
  border-radius: 18px 18px 18px 4px !important;
72
  padding: 12px 16px !important;
73
  margin-right: 12px !important;
 
74
  border: 1px solid #e2e8f0 !important;
75
  }
76
 
77
- /* Hide avatars */
78
- .stChatMessage img { display: none !important; }
79
-
80
- /* Chat Input: Full Glass Fix */
81
- .stChatInputContainer,
82
- .stChatInputContainer div,
83
- .stChatInputContainer div:focus-within,
84
- .stChatInputContainer div:hover {
85
- background: transparent !important;
86
  border: none !important;
87
- box-shadow: none !important;
 
88
  }
 
89
 
90
- /* Outer input container styling */
91
  .stChatInputContainer > div {
92
- border: 1px solid rgba(255, 255, 255, 0.3) !important;
93
  border-radius: 24px !important;
94
- background: rgba(255, 255, 255, 0.15) !important;
95
  backdrop-filter: blur(10px) !important;
96
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05) !important;
 
97
  }
98
-
99
- /* The actual textarea */
100
  .stChatInputContainer textarea {
101
- background: transparent !important;
102
- color: white !important;
103
  border: none !important;
 
104
  padding: 12px 20px !important;
105
- font-size: 16px;
106
- resize: none;
 
 
107
  }
108
-
109
- /* Placeholder */
110
  .stChatInputContainer textarea::placeholder {
111
- color: rgba(255, 255, 255, 0.7) !important;
112
- opacity: 1;
113
  }
114
-
115
- /* Focus state */
116
- .stChatInputContainer textarea:focus {
117
- outline: none !important;
118
- box-shadow: none !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  }
120
  </style>
121
  """, unsafe_allow_html=True)
122
 
123
- # Session state
124
  if "messages" not in st.session_state:
125
  st.session_state.messages = []
126
 
127
- # API key
128
  OPENROUTER_API_KEY = os.environ.get("OPENROUTER_API_KEY")
129
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  def get_ai_response(messages, model="openai/gpt-3.5-turbo"):
131
  if not OPENROUTER_API_KEY:
132
- return "No API key found."
133
 
134
  url = "https://openrouter.ai/api/v1/chat/completions"
135
  headers = {
136
- "Authorization": f"Bearer {OPENROUTER_API_KEY}",
137
  "Content-Type": "application/json"
138
  }
139
 
140
- api_messages = [{"role": "system", "content": "You are a helpful AI assistant."}]
141
  api_messages.extend(messages)
142
 
143
  data = {
144
- "model": model,
145
- "messages": api_messages,
146
- "stream": True,
147
- "temperature": 0.7,
148
- "max_tokens": 1500
149
- }
150
 
151
  try:
152
  response = requests.post(url, headers=headers, json=data, stream=True, timeout=30)
 
 
153
  full_response = ""
154
  for line in response.iter_lines():
155
  if line:
156
- line = line.decode('utf-8')
157
- if line.startswith('data: '):
158
- data_str = line[6:].strip()
159
- if data_str == '[DONE]':
160
- break
161
- try:
162
- data = json.loads(data_str)
163
- if 'choices' in data and data['choices']:
164
- delta = data['choices'][0].get('delta', {})
165
  if 'content' in delta:
166
  full_response += delta['content']
167
  yield full_response
168
- except:
169
  continue
170
  except Exception as e:
171
- yield "Sorry, something went wrong."
172
 
173
- # Header
174
  st.markdown('<h1 class="main-title">AI Assistant</h1>', unsafe_allow_html=True)
175
  st.markdown('<p class="main-subtitle">Ask me anything</p>', unsafe_allow_html=True)
176
 
177
- # Sidebar
178
  with st.sidebar:
179
  st.header("Settings")
180
 
181
  # API Status
182
- status = "Connected" if OPENROUTER_API_KEY else "No API Key"
183
  if status == "Connected":
184
  st.success("API Connected")
185
- else:
186
  st.error("No API Key")
 
 
187
 
188
- # Model
189
- models = ["openai/gpt-3.5-turbo", "openai/gpt-4", "anthropic/claude-3-haiku"]
190
- selected_model = st.selectbox("Model", models)
 
 
 
 
 
 
 
 
 
 
 
 
191
 
192
- # Clear
193
  if st.button("Clear Chat", use_container_width=True):
194
  st.session_state.messages = []
195
  st.rerun()
196
 
197
- # Welcome message
198
  if not st.session_state.messages:
199
- st.markdown('<div class="welcome-message">How can I help you today?</div>', unsafe_allow_html=True)
 
 
 
200
 
201
  # Display chat messages
202
  for message in st.session_state.messages:
203
  with st.chat_message(message["role"]):
204
  st.markdown(message["content"])
205
 
206
- # Chat input
207
  if prompt := st.chat_input("Ask anything..."):
 
208
  st.session_state.messages.append({"role": "user", "content": prompt})
209
 
 
210
  with st.chat_message("user"):
211
  st.markdown(prompt)
212
 
 
213
  with st.chat_message("assistant"):
214
  placeholder = st.empty()
 
215
  full_response = ""
216
  for response in get_ai_response(st.session_state.messages, selected_model):
217
  full_response = response
218
  placeholder.markdown(full_response + "▌")
 
219
  placeholder.markdown(full_response)
220
 
 
221
  st.session_state.messages.append({"role": "assistant", "content": full_response})
 
 
1
  import requests
2
  import os
3
  import json
4
+ import time
5
 
6
+ # Page configuration
7
  st.set_page_config(
8
  page_title="AI Assistant",
9
  page_icon="💬",
 
10
  initial_sidebar_state="collapsed"
11
  )
12
 
13
+ # Professional styling - ChatGPT inspired
14
  st.markdown("""
15
  <style>
16
+ /* Import clean fonts */
17
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&display=swap');
18
+
19
+ /* Global app styling */
20
  .stApp {
21
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
22
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
23
+ font-weight: 400;
24
  }
25
 
26
+ /* Hide Streamlit branding and clutter */
27
+ #MainMenu {visibility: hidden;}
28
+ footer {visibility: hidden;}
29
+ header {visibility: hidden;}
30
+ .stDeployButton {display: none;}
31
+
32
+ /* Main container - centered and spacious */
33
+ .main .block-container {
34
+ max-width: 800px;
35
+ padding-top: 2rem;
36
+ padding-bottom: 2rem;
37
+ }
38
 
39
+ /* Professional header styling */
40
  .main-title {
41
  text-align: center;
42
  font-size: 2.5rem;
43
  font-weight: 600;
44
  color: #2d3748;
45
  margin-bottom: 0.5rem;
46
+ letter-spacing: -0.025em;
47
  }
48
 
49
  .main-subtitle {
 
50
  font-size: 1.1rem;
51
  color: #718096;
52
  margin-bottom: 3rem;
53
+ font-weight: 400;
54
  }
55
 
56
+ /* Welcome message - centered */
57
  .welcome-message {
58
  text-align: center;
59
  font-size: 1.2rem;
60
  color: #4a5568;
61
  margin: 4rem 0;
62
+ font-weight: 400;
63
+ line-height: 1.6;
64
+ }
65
+
66
+ /* Chat messages styling */
67
+ .stChatMessage {
68
+ border: none !important;
69
+ margin-bottom: 1rem;
70
+ border-radius: 16px !important;
71
  }
72
 
73
+ /* User messages - Right side, blue */
74
  .stChatMessage[data-testid*="user"] {
75
  flex-direction: row-reverse !important;
76
  margin-left: 15% !important;
77
+ margin-right: 0% !important;
78
  }
79
 
80
  .stChatMessage[data-testid*="user"] .stMarkdown {
 
 
81
  border-radius: 18px 18px 4px 18px !important;
82
  padding: 12px 16px !important;
83
  margin-left: 12px !important;
84
+ box-shadow: 0 1px 2px rgba(0,0,0,0.1) !important;
85
  }
86
 
87
+ /* AI messages - Left side, light gray */
88
  .stChatMessage[data-testid*="assistant"] {
89
  margin-right: 15% !important;
90
+ margin-left: 0% !important;
91
  }
92
 
93
  .stChatMessage[data-testid*="assistant"] .stMarkdown {
 
 
94
  border-radius: 18px 18px 18px 4px !important;
95
  padding: 12px 16px !important;
96
  margin-right: 12px !important;
97
+ box-shadow: 0 1px 2px rgba(0,0,0,0.1) !important;
98
  border: 1px solid #e2e8f0 !important;
99
  }
100
 
101
+ /* Hide chat avatars */
102
+ .stChatMessage img {
103
+ display: none !important;
104
+ }
105
+
106
+ /* Beautiful chat input - transparent */
107
+ .stChatInputContainer {
 
 
108
  border: none !important;
109
+ background: transparent !important;
110
+ padding: 2rem 0 !important;
111
  }
112
+
113
 
 
114
  .stChatInputContainer > div {
115
+ border: 1px solid rgba(255,255,255,0.3) !important;
116
  border-radius: 24px !important;
117
+ background: rgba(255,255,255,0.15) !important;
118
  backdrop-filter: blur(10px) !important;
119
+ box-shadow: none !important;
120
+ padding: 2px !important;
121
  }
122
+
 
123
  .stChatInputContainer textarea {
 
 
124
  border: none !important;
125
+ background: transparent !important;
126
  padding: 12px 20px !important;
127
+ font-size: 1rem !important;
128
+ color: white !important;
129
+ font-family: 'Inter', sans-serif !important;
130
+ resize: none !important;
131
  }
132
+
 
133
  .stChatInputContainer textarea::placeholder {
134
+ color: rgba(255,255,255,0.7) !important;
135
+ font-weight: 400 !important;
136
  }
137
+
138
+ /* Sidebar styling */
139
+ .css-1d391kg {
140
+ background: rgba(255,255,255,0.95) !important;
141
+ border-right: 1px solid #e2e8f0 !important;
142
+ }
143
+
144
+ /* Clean buttons */
145
+ .stButton > button {
146
+ border: 1px solid #d1d5db !important;
147
+ border-radius: 8px !important;
148
+ background: white !important;
149
+ color: #374151 !important;
150
+ font-weight: 500 !important;
151
+ transition: all 0.2s !important;
152
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1) !important;
153
+ }
154
+
155
+ .stButton > button:hover {
156
+ background: #f9fafb !important;
157
+ border-color: #9ca3af !important;
158
+ }
159
+
160
+ /* Status indicators */
161
+ .stSuccess, .stError, .stWarning {
162
+ border-radius: 8px !important;
163
+ border: none !important;
164
+ font-weight: 500 !important;
165
  }
166
  </style>
167
  """, unsafe_allow_html=True)
168
 
169
+ # Initialize session state
170
  if "messages" not in st.session_state:
171
  st.session_state.messages = []
172
 
173
+ # Get API key
174
  OPENROUTER_API_KEY = os.environ.get("OPENROUTER_API_KEY")
175
 
176
+ @st.cache_data(ttl=300)
177
+ def check_api_status():
178
+ if not OPENROUTER_API_KEY:
179
+ return "No API Key"
180
+ try:
181
+ url = "https://openrouter.ai/api/v1/models"
182
+ headers = {"Authorization": f"Bearer {OPENROUTER_API_KEY}"}
183
+ response = requests.get(url, headers=headers, timeout=5)
184
+ return "Connected" if response.status_code == 200 else "Error"
185
+ except:
186
+ return "Error"
187
+
188
  def get_ai_response(messages, model="openai/gpt-3.5-turbo"):
189
  if not OPENROUTER_API_KEY:
190
+ return "No API key found. Please add OPENROUTER_API_KEY to environment variables."
191
 
192
  url = "https://openrouter.ai/api/v1/chat/completions"
193
  headers = {
 
194
  "Content-Type": "application/json"
195
  }
196
 
197
+ api_messages = [{"role": "system", "content": "You are a helpful AI assistant. Provide clear and helpful responses."}]
198
  api_messages.extend(messages)
199
 
200
  data = {
 
 
 
 
 
 
201
 
202
  try:
203
  response = requests.post(url, headers=headers, json=data, stream=True, timeout=30)
204
+ response.raise_for_status()
205
+
206
  full_response = ""
207
  for line in response.iter_lines():
208
  if line:
 
 
 
 
 
 
 
 
 
209
  if 'content' in delta:
210
  full_response += delta['content']
211
  yield full_response
212
+ except json.JSONDecodeError:
213
  continue
214
  except Exception as e:
215
+ yield f"Sorry, I encountered an error. Please try again."
216
 
217
+ # Clean, professional header
218
  st.markdown('<h1 class="main-title">AI Assistant</h1>', unsafe_allow_html=True)
219
  st.markdown('<p class="main-subtitle">Ask me anything</p>', unsafe_allow_html=True)
220
 
221
+ # Sidebar (collapsed by default)
222
  with st.sidebar:
223
  st.header("Settings")
224
 
225
  # API Status
226
+ status = check_api_status()
227
  if status == "Connected":
228
  st.success("API Connected")
229
+ elif status == "No API Key":
230
  st.error("No API Key")
231
+ else:
232
+ st.warning("Connection Issue")
233
 
234
+ st.divider()
235
+
236
+ # Model selection
237
+ models = [
238
+ "openai/gpt-3.5-turbo",
239
+ "openai/gpt-4",
240
+ "anthropic/claude-3-haiku",
241
+ "google/gemini-pro"
242
+ ]
243
+
244
+ selected_model = st.selectbox("Model", models, index=0)
245
+
246
+ st.divider()
247
+
248
+
249
 
250
+ # Controls
251
  if st.button("Clear Chat", use_container_width=True):
252
  st.session_state.messages = []
253
  st.rerun()
254
 
255
+ # Show welcome message when no messages
256
  if not st.session_state.messages:
257
+ st.markdown(
258
+ '<div class="welcome-message">How can I help you today?</div>',
259
+ unsafe_allow_html=True
260
+ )
261
 
262
  # Display chat messages
263
  for message in st.session_state.messages:
264
  with st.chat_message(message["role"]):
265
  st.markdown(message["content"])
266
 
267
+ # Chat input with inviting placeholder
268
  if prompt := st.chat_input("Ask anything..."):
269
+ # Add user message
270
  st.session_state.messages.append({"role": "user", "content": prompt})
271
 
272
+ # Display user message
273
  with st.chat_message("user"):
274
  st.markdown(prompt)
275
 
276
+ # Get AI response
277
  with st.chat_message("assistant"):
278
  placeholder = st.empty()
279
+
280
  full_response = ""
281
  for response in get_ai_response(st.session_state.messages, selected_model):
282
  full_response = response
283
  placeholder.markdown(full_response + "▌")
284
+
285
  placeholder.markdown(full_response)
286
 
287
+ # Add AI response to messages
288
  st.session_state.messages.append({"role": "assistant", "content": full_response})