uumerrr684 commited on
Commit
1595043
·
verified ·
1 Parent(s): 173a005

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +119 -519
app.py CHANGED
@@ -1,561 +1,161 @@
1
- import streamlit as st
2
- import time
3
  import requests
 
4
  import json
5
- from datetime import datetime
6
 
7
  # Page configuration
8
  st.set_page_config(
9
  page_title="AI Assistant",
10
- page_icon="🤖",
11
- layout="wide",
12
- initial_sidebar_state="expanded"
13
  )
14
 
15
- # Custom CSS to match the React design
16
  st.markdown("""
17
  <style>
18
- /* Main background gradient */
19
  .stApp {
20
- background: linear-gradient(135deg, #EEF2FF 0%, #E0E7FF 100%);
21
- }
22
-
23
- /* Sidebar styling */
24
- .css-1d391kg, [data-testid="stSidebar"] {
25
- background-color: white;
26
- border-right: 1px solid #E5E7EB;
27
- box-shadow: 2px 0 10px rgba(0,0,0,0.05);
28
- }
29
-
30
- /* Header styling */
31
- .header-container {
32
- background: white;
33
- border-bottom: 1px solid #E5E7EB;
34
- padding: 1rem;
35
- margin: -1rem -1rem 1rem -1rem;
36
- display: flex;
37
- align-items: center;
38
- gap: 12px;
39
- }
40
-
41
- .header-avatar {
42
- width: 40px;
43
- height: 40px;
44
- background: linear-gradient(135deg, #3B82F6 0%, #9333EA 100%);
45
- border-radius: 50%;
46
- display: flex;
47
- align-items: center;
48
- justify-content: center;
49
- color: white;
50
- font-size: 20px;
51
- }
52
-
53
- .header-text h1 {
54
- margin: 0;
55
- font-size: 1.25rem;
56
- font-weight: 600;
57
- color: #1F2937;
58
- }
59
-
60
- .header-text p {
61
- margin: 0;
62
- font-size: 0.875rem;
63
- color: #6B7280;
64
- }
65
-
66
- /* Message styling */
67
- .user-message {
68
- background-color: #3B82F6;
69
- color: white;
70
- padding: 0.75rem 1rem;
71
- border-radius: 12px;
72
- border-bottom-right-radius: 4px;
73
- margin: 0.5rem 0;
74
- max-width: 70%;
75
- float: right;
76
- clear: both;
77
- }
78
-
79
- .assistant-message {
80
- background-color: white;
81
- color: #1F2937;
82
- padding: 0.75rem 1rem;
83
- border: 1px solid #E5E7EB;
84
- border-radius: 12px;
85
- border-bottom-left-radius: 4px;
86
- margin: 0.5rem 0;
87
- max-width: 70%;
88
- float: left;
89
- clear: both;
90
- }
91
-
92
- /* Avatar styling */
93
- .message-container {
94
- display: flex;
95
- align-items: flex-start;
96
- margin: 1rem 0;
97
- gap: 12px;
98
- }
99
-
100
- .message-container.user {
101
- flex-direction: row-reverse;
102
- }
103
-
104
- .avatar {
105
- width: 32px;
106
- height: 32px;
107
- border-radius: 50%;
108
- display: flex;
109
- align-items: center;
110
- justify-content: center;
111
- flex-shrink: 0;
112
- font-size: 14px;
113
- }
114
-
115
- .avatar.user {
116
- background-color: #3B82F6;
117
- color: white;
118
- }
119
-
120
- .avatar.assistant {
121
- background-color: #E5E7EB;
122
- color: #6B7280;
123
- }
124
-
125
- /* Welcome screen styling */
126
- .welcome-container {
127
- text-align: center;
128
- padding: 3rem 0;
129
- }
130
-
131
- .welcome-icon {
132
- width: 64px;
133
- height: 64px;
134
- background: linear-gradient(135deg, #3B82F6 0%, #9333EA 100%);
135
- border-radius: 50%;
136
- display: flex;
137
- align-items: center;
138
- justify-content: center;
139
- margin: 0 auto 1rem;
140
- color: white;
141
- font-size: 32px;
142
- }
143
-
144
- .example-prompt {
145
  background: white;
146
- border: 1px solid #E5E7EB;
147
- border-radius: 8px;
148
- padding: 0.75rem;
149
- margin: 0.5rem;
150
- cursor: pointer;
151
- transition: all 0.2s;
152
- text-align: left;
153
- }
154
-
155
- .example-prompt:hover {
156
- border-color: #93C5FD;
157
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
158
- }
159
-
160
- /* Input area styling */
161
- .stTextArea textarea {
162
- border-radius: 8px !important;
163
- border: 1px solid #D1D5DB !important;
164
- padding: 0.75rem !important;
165
- }
166
-
167
- .stTextArea textarea:focus {
168
- border-color: #3B82F6 !important;
169
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1) !important;
170
- }
171
-
172
- /* Button styling */
173
- .stButton button {
174
- background: linear-gradient(135deg, #3B82F6 0%, #6366F1 100%);
175
- color: white;
176
- border: none;
177
- border-radius: 8px;
178
- padding: 0.5rem 1rem;
179
- font-weight: 500;
180
- transition: all 0.2s;
181
  }
182
 
183
- .stButton button:hover {
184
- background: linear-gradient(135deg, #2563EB 0%, #4F46E5 100%);
185
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
186
  }
187
 
188
- /* Status indicator */
189
- .status-indicator {
190
- display: flex;
191
- align-items: center;
192
- gap: 8px;
193
- font-size: 0.875rem;
194
- margin-top: 1rem;
195
- }
196
-
197
- .status-indicator.ready {
198
- color: #10B981;
199
- }
200
-
201
- .status-indicator.error {
202
- color: #EF4444;
203
- }
204
-
205
- .status-dot {
206
- width: 8px;
207
- height: 8px;
208
- border-radius: 50%;
209
- animation: pulse 2s infinite;
210
- }
211
-
212
- .status-dot.ready {
213
- background-color: #10B981;
214
- }
215
-
216
- .status-dot.error {
217
- background-color: #EF4444;
218
- }
219
-
220
- @keyframes pulse {
221
- 0%, 100% {
222
- opacity: 1;
223
- }
224
- 50% {
225
- opacity: 0.5;
226
- }
227
- }
228
-
229
- /* Loading animation */
230
- .loading-dots {
231
- display: flex;
232
- gap: 4px;
233
- padding: 0.75rem 1rem;
234
- background: white;
235
- border: 1px solid #E5E7EB;
236
- border-radius: 12px;
237
- border-bottom-left-radius: 4px;
238
- width: fit-content;
239
- }
240
-
241
- .loading-dot {
242
- width: 8px;
243
- height: 8px;
244
- background-color: #9CA3AF;
245
- border-radius: 50%;
246
- animation: bounce 1.4s infinite ease-in-out both;
247
- }
248
-
249
- .loading-dot:nth-child(1) {
250
- animation-delay: -0.32s;
251
- }
252
-
253
- .loading-dot:nth-child(2) {
254
- animation-delay: -0.16s;
255
- }
256
-
257
- @keyframes bounce {
258
- 0%, 80%, 100% {
259
- transform: scale(0);
260
- }
261
- 40% {
262
- transform: scale(1);
263
- }
264
- }
265
-
266
- /* API Key input styling */
267
- .stTextInput input {
268
- border-radius: 8px !important;
269
- border: 1px solid #D1D5DB !important;
270
- padding: 0.5rem !important;
271
- font-family: monospace !important;
272
- }
273
-
274
- .api-key-section {
275
- background: #FEF3C7;
276
- border: 1px solid #FCD34D;
277
- border-radius: 8px;
278
- padding: 1rem;
279
- margin-bottom: 1rem;
280
- }
281
-
282
- .api-key-section h4 {
283
- color: #92400E;
284
- margin-bottom: 0.5rem;
285
- }
286
-
287
- .api-key-section p {
288
- color: #78350F;
289
- font-size: 0.875rem;
290
- margin-bottom: 0.5rem;
291
- }
292
  </style>
293
  """, unsafe_allow_html=True)
294
 
295
  # Initialize session state
296
- if 'messages' not in st.session_state:
297
  st.session_state.messages = []
298
- if 'selected_model' not in st.session_state:
299
- st.session_state.selected_model = 'openai/gpt-3.5-turbo'
300
- if 'input_text' not in st.session_state:
301
- st.session_state.input_text = ""
302
- if 'api_key' not in st.session_state:
303
- st.session_state.api_key = ""
304
 
305
- # Model options
306
- models = {
307
- 'openai/gpt-3.5-turbo': 'GPT-3.5 Turbo',
308
- 'openai/gpt-4': 'GPT-4',
309
- 'openai/gpt-4-turbo': 'GPT-4 Turbo',
310
- 'anthropic/claude-3-haiku': 'Claude 3 Haiku',
311
- 'anthropic/claude-3-opus': 'Claude 3 Opus',
312
- 'anthropic/claude-3-sonnet': 'Claude 3 Sonnet',
313
- 'google/gemini-pro': 'Gemini Pro',
314
- 'google/gemini-pro-1.5': 'Gemini Pro 1.5',
315
- 'meta-llama/llama-3-70b-instruct': 'Llama 3 70B',
316
- 'mistralai/mixtral-8x7b-instruct': 'Mixtral 8x7B'
317
- }
318
 
319
- def call_openrouter_api(messages, model, api_key):
320
- """Call OpenRouter API with the given messages and model."""
 
 
321
  try:
322
- headers = {
323
- "Authorization": f"Bearer {api_key}",
324
- "HTTP-Referer": "http://localhost:8501", # Optional, can be your app URL
325
- "X-Title": "AI Assistant", # Optional, shows in OpenRouter dashboard
326
- "Content-Type": "application/json"
327
- }
328
-
329
- data = {
330
- "model": model,
331
- "messages": messages,
332
- "temperature": 0.7,
333
- "max_tokens": 1000
334
- }
335
-
336
- response = requests.post(
337
- "https://openrouter.ai/api/v1/chat/completions",
338
- headers=headers,
339
- json=data,
340
- timeout=30
341
- )
 
 
 
 
 
 
 
 
 
 
 
342
 
343
- if response.status_code == 200:
344
- result = response.json()
345
- return result['choices'][0]['message']['content'], None
346
- else:
347
- error_msg = f"API Error: {response.status_code} - {response.text}"
348
- return None, error_msg
349
-
350
- except requests.exceptions.Timeout:
351
- return None, "Request timed out. Please try again."
352
- except requests.exceptions.RequestException as e:
353
- return None, f"Connection error: {str(e)}"
 
 
 
 
 
 
354
  except Exception as e:
355
- return None, f"Unexpected error: {str(e)}"
 
 
 
 
356
 
357
  # Sidebar
358
  with st.sidebar:
359
- st.markdown("### ⚙️ Settings")
360
-
361
- # API Key Section
362
- st.markdown("""
363
- <div class="api-key-section">
364
- <h4>🔑 OpenRouter API Key</h4>
365
- <p>Get your API key from <a href="https://openrouter.ai/keys" target="_blank">openrouter.ai/keys</a></p>
366
- </div>
367
- """, unsafe_allow_html=True)
368
 
369
- api_key_input = st.text_input(
370
- "API Key",
371
- type="password",
372
- value=st.session_state.api_key,
373
- placeholder="sk-or-v1-...",
374
- help="Your OpenRouter API key for accessing AI models",
375
- label_visibility="collapsed"
376
- )
377
-
378
- if api_key_input:
379
- st.session_state.api_key = api_key_input
380
 
381
- st.markdown("---")
382
 
383
  # Model selection
384
- st.markdown("### 🤖 AI Model")
385
- st.session_state.selected_model = st.selectbox(
386
- "Select Model",
387
- options=list(models.keys()),
388
- format_func=lambda x: models[x],
389
- key="model_select",
390
- label_visibility="collapsed"
391
- )
392
 
393
- # Model info
394
- st.info(f"📊 Using: {models[st.session_state.selected_model]}")
395
 
396
- st.markdown("---")
397
 
398
- # Clear chat button
399
- if st.button("🗑️ Clear Chat", use_container_width=True):
400
  st.session_state.messages = []
401
  st.rerun()
402
-
403
- # API Status
404
- if st.session_state.api_key:
405
- st.markdown("""
406
- <div class="status-indicator ready">
407
- <div class="status-dot ready"></div>
408
- <span>API Ready</span>
409
- </div>
410
- """, unsafe_allow_html=True)
411
- else:
412
- st.markdown("""
413
- <div class="status-indicator error">
414
- <div class="status-dot error"></div>
415
- <span>API Key Required</span>
416
- </div>
417
- """, unsafe_allow_html=True)
418
 
419
- # Main chat area
420
- col1, col2, col3 = st.columns([1, 6, 1])
 
421
 
422
- with col2:
423
- # Header
424
- st.markdown(f"""
425
- <div class="header-container">
426
- <div class="header-avatar">🤖</div>
427
- <div class="header-text">
428
- <h1>AI Assistant</h1>
429
- <p>Powered by {models[st.session_state.selected_model]}</p>
430
- </div>
431
- </div>
432
- """, unsafe_allow_html=True)
433
-
434
- # Check if API key is set
435
- if not st.session_state.api_key:
436
- st.warning("⚠️ Please enter your OpenRouter API key in the sidebar to start chatting.")
437
- st.markdown("""
438
- ### How to get started:
439
- 1. Go to [OpenRouter](https://openrouter.ai/keys) and sign up/login
440
- 2. Create a new API key
441
- 3. Paste it in the sidebar
442
- 4. Start chatting with your preferred AI model!
443
- """)
444
-
445
- # Message container
446
- messages_container = st.container()
447
-
448
- # Welcome screen or messages
449
- if not st.session_state.messages:
450
- with messages_container:
451
- st.markdown("""
452
- <div class="welcome-container">
453
- <div class="welcome-icon">⚡</div>
454
- <h2 style="color: #1F2937; margin-bottom: 0.5rem;">Welcome to AI Assistant</h2>
455
- <p style="color: #6B7280; margin-bottom: 1.5rem;">Start a conversation or try one of these examples:</p>
456
- </div>
457
- """, unsafe_allow_html=True)
458
-
459
- # Example prompts
460
- example_prompts = [
461
- "Help me write a professional email",
462
- "Explain quantum computing in simple terms",
463
- "Give me 5 creative writing prompts",
464
- "What are the latest web development trends?"
465
- ]
466
-
467
- cols = st.columns(2)
468
- for i, prompt in enumerate(example_prompts):
469
- with cols[i % 2]:
470
- if st.button(prompt, key=f"example_{i}", use_container_width=True):
471
- st.session_state.input_text = prompt
472
- st.rerun()
473
- else:
474
- # Display messages
475
- with messages_container:
476
- for message in st.session_state.messages:
477
- if message["role"] == "user":
478
- st.markdown(f"""
479
- <div class="message-container user">
480
- <div class="avatar user">👤</div>
481
- <div class="user-message">{message["content"]}</div>
482
- </div>
483
- """, unsafe_allow_html=True)
484
- else:
485
- st.markdown(f"""
486
- <div class="message-container">
487
- <div class="avatar assistant">🤖</div>
488
- <div class="assistant-message">{message["content"]}</div>
489
- </div>
490
- """, unsafe_allow_html=True)
491
-
492
- # Input area
493
- st.markdown("<br>", unsafe_allow_html=True)
494
-
495
- input_col1, input_col2 = st.columns([6, 1])
496
-
497
- with input_col1:
498
- user_input = st.text_area(
499
- "Type your message here...",
500
- key="user_input",
501
- height=70,
502
- value=st.session_state.input_text,
503
- label_visibility="collapsed",
504
- disabled=not st.session_state.api_key
505
- )
506
-
507
- with input_col2:
508
- send_button = st.button(
509
- "📤 Send",
510
- use_container_width=True,
511
- disabled=not st.session_state.api_key
512
- )
513
-
514
- # Handle send
515
- if send_button and user_input and st.session_state.api_key:
516
- # Add user message
517
- st.session_state.messages.append({"role": "user", "content": user_input})
518
-
519
- # Prepare messages for API
520
- api_messages = []
521
- for msg in st.session_state.messages:
522
- api_messages.append({
523
- "role": msg["role"],
524
- "content": msg["content"]
525
- })
526
 
527
- # Show loading animation
528
- with messages_container:
529
- with st.spinner("Thinking..."):
530
- # Call OpenRouter API
531
- response_content, error = call_openrouter_api(
532
- api_messages,
533
- st.session_state.selected_model,
534
- st.session_state.api_key
535
- )
536
-
537
- if error:
538
- st.error(f"❌ {error}")
539
- # Add error message to chat
540
- error_response = f"Sorry, I encountered an error: {error}\n\nPlease check your API key and try again."
541
- st.session_state.messages.append({"role": "assistant", "content": error_response})
542
- else:
543
- # Add assistant response
544
- st.session_state.messages.append({"role": "assistant", "content": response_content})
545
 
546
- # Clear input
547
- st.session_state.input_text = ""
548
- st.rerun()
549
-
550
- # Auto-scroll to bottom (Streamlit does this automatically)
551
- if st.session_state.messages:
552
- st.markdown("<script>window.scrollTo(0, document.body.scrollHeight);</script>", unsafe_allow_html=True)
553
-
554
- # Footer info
555
- with col2:
556
- if st.session_state.api_key:
557
- st.markdown("---")
558
- st.caption("Connected to OpenRouter API | Chat powered by " + models[st.session_state.selected_model])
559
- else:
560
- st.markdown("---")
561
- st.caption("Not connected - Please add your OpenRouter API key in the sidebar")
 
 
 
1
  import requests
2
+ import os
3
  import json
4
+ import streamlit as st
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
+ # White background
14
  st.markdown("""
15
  <style>
 
16
  .stApp {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  background: white;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  }
19
 
20
+ .main .block-container {
21
+ max-width: 800px;
 
22
  }
23
 
24
+ #MainMenu {visibility: hidden;}
25
+ footer {visibility: hidden;}
26
+ header {visibility: hidden;}
27
+ .stDeployButton {display: none;}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  </style>
29
  """, unsafe_allow_html=True)
30
 
31
  # Initialize session state
32
+ if "messages" not in st.session_state:
33
  st.session_state.messages = []
 
 
 
 
 
 
34
 
35
+ # Get API key
36
+ OPENROUTER_API_KEY = os.environ.get("OPENROUTER_API_KEY")
 
 
 
 
 
 
 
 
 
 
 
37
 
38
+ @st.cache_data(ttl=300)
39
+ def check_api_status():
40
+ if not OPENROUTER_API_KEY:
41
+ return "No API Key"
42
  try:
43
+ url = "https://openrouter.ai/api/v1/models"
44
+ headers = {"Authorization": f"Bearer {OPENROUTER_API_KEY}"}
45
+ response = requests.get(url, headers=headers, timeout=5)
46
+ return "Connected" if response.status_code == 200 else "Error"
47
+ except:
48
+ return "Error"
49
+
50
+ def get_ai_response(messages, model="openai/gpt-3.5-turbo"):
51
+ if not OPENROUTER_API_KEY:
52
+ return "No API key found. Please add OPENROUTER_API_KEY to environment variables."
53
+
54
+ url = "https://openrouter.ai/api/v1/chat/completions"
55
+ headers = {
56
+ "Content-Type": "application/json",
57
+ "Authorization": f"Bearer {OPENROUTER_API_KEY}"
58
+ }
59
+
60
+ api_messages = [{"role": "system", "content": "You are a helpful AI assistant. Provide clear and helpful responses."}]
61
+ api_messages.extend(messages)
62
+
63
+ data = {
64
+ "model": model,
65
+ "messages": api_messages,
66
+ "stream": True,
67
+ "max_tokens": 1000,
68
+ "temperature": 0.7
69
+ }
70
+
71
+ try:
72
+ response = requests.post(url, headers=headers, json=data, stream=True, timeout=30)
73
+ response.raise_for_status()
74
 
75
+ full_response = ""
76
+ for line in response.iter_lines():
77
+ if line:
78
+ line_str = line.decode('utf-8')
79
+ if line_str.startswith('data: '):
80
+ line_str = line_str[6:]
81
+ if line_str.strip() == '[DONE]':
82
+ break
83
+ try:
84
+ data = json.loads(line_str)
85
+ if 'choices' in data and len(data['choices']) > 0:
86
+ delta = data['choices'][0].get('delta', {})
87
+ if 'content' in delta:
88
+ full_response += delta['content']
89
+ yield full_response
90
+ except json.JSONDecodeError:
91
+ continue
92
  except Exception as e:
93
+ yield f"Sorry, I encountered an error. Please try again."
94
+
95
+ # Header
96
+ st.title("AI Assistant")
97
+ st.caption("Ask me anything")
98
 
99
  # Sidebar
100
  with st.sidebar:
101
+ st.header("Settings")
 
 
 
 
 
 
 
 
102
 
103
+ # API Status
104
+ status = check_api_status()
105
+ if status == "Connected":
106
+ st.success("API Connected")
107
+ elif status == "No API Key":
108
+ st.error("No API Key")
109
+ else:
110
+ st.warning("Connection Issue")
 
 
 
111
 
112
+ st.divider()
113
 
114
  # Model selection
115
+ models = [
116
+ "openai/gpt-3.5-turbo",
117
+ "openai/gpt-4",
118
+ "anthropic/claude-3-haiku",
119
+ "google/gemini-pro"
120
+ ]
 
 
121
 
122
+ selected_model = st.selectbox("Model", models, index=0)
 
123
 
124
+ st.divider()
125
 
126
+ # Controls
127
+ if st.button("Clear Chat", use_container_width=True):
128
  st.session_state.messages = []
129
  st.rerun()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
+ # Show welcome message when no messages
132
+ if not st.session_state.messages:
133
+ st.info("How can I help you today?")
134
 
135
+ # Display chat messages
136
+ for message in st.session_state.messages:
137
+ with st.chat_message(message["role"]):
138
+ st.markdown(message["content"])
139
+
140
+ # Chat input
141
+ if prompt := st.chat_input("Ask anything..."):
142
+ # Add user message
143
+ st.session_state.messages.append({"role": "user", "content": prompt})
144
+
145
+ # Display user message
146
+ with st.chat_message("user"):
147
+ st.markdown(prompt)
148
+
149
+ # Get AI response
150
+ with st.chat_message("assistant"):
151
+ placeholder = st.empty()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
 
153
+ full_response = ""
154
+ for response in get_ai_response(st.session_state.messages, selected_model):
155
+ full_response = response
156
+ placeholder.markdown(full_response + "▌")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
 
158
+ placeholder.markdown(full_response)
159
+
160
+ # Add AI response to messages
161
+ st.session_state.messages.append({"role": "assistant", "content": full_response})