rdune71 commited on
Commit
0757010
ยท
1 Parent(s): 070ec84

Fixed app layout to move chat input outside of tabs to comply with Streamlit constraints

Browse files
Files changed (1) hide show
  1. app.py +309 -285
app.py CHANGED
@@ -44,321 +44,321 @@ if "ngrok_url_temp" not in st.session_state:
44
  if "hf_expert_requested" not in st.session_state:
45
  st.session_state.hf_expert_requested = False
46
 
47
- # Add evaluation dashboard tab
48
- tab1, tab2, tab3 = st.tabs(["๐Ÿ’ฌ Chat", "๐Ÿ”ฌ Evaluate AI", "๐Ÿ“Š Reports"])
49
-
50
- with tab1:
51
- # Sidebar layout redesign
52
- with st.sidebar:
53
- st.title("๐Ÿง  AI Life Coach")
54
- st.markdown("Your personal AI-powered life development assistant")
55
-
56
- # PRIMARY ACTIONS
57
- st.subheader("๐Ÿ’ฌ Primary Actions")
58
- model_options = {
59
- "Mistral 7B (Local)": "mistral:latest",
60
- "Llama 2 7B (Local)": "llama2:latest",
61
- "OpenChat 3.5 (Local)": "openchat:latest"
62
- }
63
- selected_model_name = st.selectbox(
64
- "Select Model",
65
- options=list(model_options.keys()),
66
- index=0,
67
- key="sidebar_model_select"
68
- )
69
- st.session_state.selected_model = model_options[selected_model_name]
70
-
71
- st.divider()
72
-
73
- # CONFIGURATION
74
- st.subheader("โš™๏ธ Configuration")
75
- ngrok_url_input = st.text_input(
76
- "Ollama Server URL",
77
- value=st.session_state.ngrok_url_temp,
78
- help="Enter your ngrok URL",
79
- key="sidebar_ngrok_url"
80
- )
81
-
82
- if ngrok_url_input != st.session_state.ngrok_url_temp:
83
- st.session_state.ngrok_url_temp = ngrok_url_input
84
- st.success("โœ… URL updated!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
- if st.button("๐Ÿ“ก Test Connection"):
87
- try:
88
- import requests
89
- headers = {
90
- "ngrok-skip-browser-warning": "true",
91
- "User-Agent": "AI-Life-Coach-Test"
92
- }
93
- with st.spinner("Testing connection..."):
94
- response = requests.get(
95
- f"{ngrok_url_input}/api/tags",
96
- headers=headers,
97
- timeout=15
98
- )
99
- if response.status_code == 200:
100
- st.success("โœ… Connection successful!")
101
- else:
102
- st.error(f"โŒ Failed: {response.status_code}")
103
- except Exception as e:
104
- st.error(f"โŒ Error: {str(e)[:50]}...")
105
 
106
- if st.button("๐Ÿ—‘๏ธ Clear History"):
107
- st.session_state.messages = []
108
- st.success("History cleared!")
 
109
 
110
  st.divider()
111
 
112
- # ADVANCED FEATURES
113
- with st.expander("๐Ÿ” Advanced Features", expanded=False):
114
- st.subheader("๐Ÿ“Š System Monitor")
115
- try:
116
- from services.ollama_monitor import check_ollama_status
117
- ollama_status = check_ollama_status()
118
- if ollama_status.get("running"):
119
- st.success("๐Ÿฆ™ Ollama: Running")
120
- else:
121
- st.warning("๐Ÿฆ™ Ollama: Not running")
122
- except:
123
- st.info("๐Ÿฆ™ Ollama: Unknown")
124
-
125
- try:
126
- from services.hf_endpoint_monitor import hf_monitor
127
- hf_status = hf_monitor.check_endpoint_status()
128
- if hf_status['available']:
129
- st.success("๐Ÿค— HF: Available")
130
- else:
131
- st.warning("๐Ÿค— HF: Not available")
132
- except:
133
- st.info("๐Ÿค— HF: Unknown")
134
-
135
- if check_redis_health():
136
- st.success("๐Ÿ’พ Redis: Connected")
137
- else:
138
- st.error("๐Ÿ’พ Redis: Disconnected")
139
-
140
- st.divider()
141
-
142
- st.subheader("๐Ÿค– HF Expert Analysis")
143
- col1, col2 = st.columns([3, 1])
144
- with col1:
145
- st.markdown("""
146
- **HF Expert Features:**
147
- - Analyzes entire conversation history
148
- - Performs web research when needed
149
- - Provides deep insights and recommendations
150
- - Acts as expert consultant in your conversation
151
- """)
152
- with col2:
153
- if st.button("๐Ÿง  Activate HF Expert",
154
- key="activate_hf_expert_sidebar",
155
- help="Send conversation to HF endpoint for deep analysis",
156
- use_container_width=True,
157
- disabled=st.session_state.is_processing):
158
- st.session_state.hf_expert_requested = True
159
 
160
- # Main interface
161
- st.title("๐Ÿง  AI Life Coach")
162
- st.markdown("Ask me anything about personal development, goal setting, or life advice!")
163
 
164
- # Display messages
165
- for message in st.session_state.messages:
166
- with st.chat_message(message["role"]):
167
- # Format HF expert messages differently
168
- if message.get("source") == "hf_expert":
169
- st.markdown("### ๐Ÿค– HF Expert Analysis")
170
- st.markdown(message["content"])
171
- else:
172
- st.markdown(message["content"])
173
- if "timestamp" in message:
174
- st.caption(f"๐Ÿ•’ {message['timestamp']}")
175
 
176
- # Manual HF Analysis Section
177
- if st.session_state.messages and len(st.session_state.messages) > 0:
178
- st.divider()
 
 
 
 
179
 
180
- # HF Expert Section
181
- with st.expander("๐Ÿค– HF Expert Analysis", expanded=False):
182
- st.subheader("Deep Conversation Analysis")
183
-
184
- col1, col2 = st.columns([3, 1])
185
- with col1:
186
- st.markdown("""
187
- **HF Expert Features:**
188
- - Analyzes entire conversation history
189
- - Performs web research when needed
190
- - Provides deep insights and recommendations
191
- - Acts as expert consultant in your conversation
192
- """)
193
-
194
- # Show conversation preview
195
- st.markdown("**Conversation Preview for HF Expert:**")
196
- st.markdown("---")
197
- for i, msg in enumerate(st.session_state.messages[-5:]): # Last 5 messages
198
- role = "๐Ÿ‘ค You" if msg["role"] == "user" else "๐Ÿค– Assistant"
199
- st.markdown(f"**{role}:** {msg['content'][:100]}{'...' if len(msg['content']) > 100 else ''}")
200
- st.markdown("---")
201
-
202
- with col2:
203
- if st.button("๐Ÿง  Activate HF Expert",
204
- key="activate_hf_expert",
205
- help="Send conversation to HF endpoint for deep analysis",
206
- use_container_width=True,
207
- disabled=st.session_state.is_processing):
208
- st.session_state.hf_expert_requested = True
209
 
210
- # Show HF expert analysis when requested
211
- if st.session_state.get("hf_expert_requested", False):
212
- with st.spinner("๐Ÿง  HF Expert analyzing conversation..."):
213
- try:
214
- # Get conversation history
215
- user_session = session_manager.get_session("default_user")
216
- conversation_history = user_session.get("conversation", [])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
 
218
- # Show what HF expert sees
219
- with st.expander("๐Ÿ“‹ HF Expert Input", expanded=False):
220
- st.markdown("**Conversation History Sent to HF Expert:**")
221
- for i, msg in enumerate(conversation_history[-10:]): # Last 10 messages
222
- st.markdown(f"**{msg['role'].capitalize()}:** {msg['content'][:100]}{'...' if len(msg['content']) > 100 else ''}")
 
 
 
 
223
 
224
- # Request HF analysis
225
- hf_analysis = coordinator.manual_hf_analysis(
226
- "default_user",
227
- conversation_history
228
- )
 
 
 
229
 
230
- if hf_analysis:
231
- # Display HF expert response with clear indication
232
- with st.chat_message("assistant"):
233
- st.markdown("### ๐Ÿค– HF Expert Analysis")
234
- st.markdown(hf_analysis)
235
-
236
- # Add research/web search decisions
237
- research_needs = coordinator.determine_web_search_needs(conversation_history)
238
- if research_needs["needs_search"]:
239
- st.info(f"๐Ÿ” **Research Needed:** {research_needs['reasoning']}")
240
- if st.button("๐Ÿ”Ž Perform Web Research", key="web_research_button"):
241
- # Perform web search
242
- with st.spinner("๐Ÿ”Ž Searching for current information..."):
243
- # Add web search logic here
244
- st.success("โœ… Web research completed!")
245
-
246
- # Add to message history with HF expert tag
247
- st.session_state.messages.append({
248
- "role": "assistant",
249
- "content": hf_analysis,
250
- "timestamp": datetime.now().strftime("%H:%M:%S"),
251
- "source": "hf_expert",
252
- "research_needs": research_needs
253
- })
254
-
255
- st.session_state.hf_expert_requested = False
256
-
257
- except Exception as e:
258
- user_msg = translate_error(e)
259
- st.error(f"โŒ HF Expert analysis failed: {user_msg}")
260
  st.session_state.hf_expert_requested = False
 
 
 
 
 
261
 
262
- # Chat input - FIXED VERSION
263
- user_input = st.chat_input("Type your message here...", disabled=st.session_state.is_processing)
264
 
265
- # Process message when received
266
- if user_input and not st.session_state.is_processing:
267
- st.session_state.is_processing = True
268
-
269
- # Display user message
270
- with st.chat_message("user"):
271
- st.markdown(user_input)
272
-
273
- st.session_state.messages.append({
274
- "role": "user",
275
- "content": user_input,
276
- "timestamp": datetime.now().strftime("%H:%M:%S")
277
- })
 
 
 
 
 
278
 
279
- # Process AI response
280
- with st.chat_message("assistant"):
281
- response_placeholder = st.empty()
282
- status_placeholder = st.empty()
 
 
 
 
 
 
283
 
284
  try:
285
- # Get conversation history
286
- user_session = session_manager.get_session("default_user")
287
- conversation = user_session.get("conversation", [])
288
- conversation_history = conversation[-5:] # Last 5 messages
289
- conversation_history.append({"role": "user", "content": user_input})
290
-
291
- # Try Ollama with proper error handling
292
- status_placeholder.info(PROCESSING_STAGES["ollama"])
293
- ai_response = None
294
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295
  try:
296
- ai_response = send_to_ollama(
297
- user_input,
298
- conversation_history,
299
- st.session_state.ngrok_url_temp,
300
- st.session_state.selected_model
301
- )
302
-
303
  if ai_response:
304
  response_placeholder.markdown(ai_response)
305
- status_placeholder.success("โœ… Response received!")
306
  else:
307
- status_placeholder.warning("โš ๏ธ Empty response from Ollama")
308
-
309
- except Exception as ollama_error:
310
- user_msg = translate_error(ollama_error)
311
  status_placeholder.error(f"โš ๏ธ {user_msg}")
312
-
313
- # Fallback to HF if available
314
- if config.hf_token and not ai_response:
315
- status_placeholder.info(PROCESSING_STAGES["hf_init"])
316
- try:
317
- ai_response = send_to_hf(user_input, conversation_history)
318
- if ai_response:
319
- response_placeholder.markdown(ai_response)
320
- status_placeholder.success("โœ… HF response received!")
321
- else:
322
- status_placeholder.error("โŒ No response from HF")
323
- except Exception as hf_error:
324
- user_msg = translate_error(hf_error)
325
- status_placeholder.error(f"โš ๏ธ {user_msg}")
326
-
327
- # Save response if successful
328
- if ai_response:
329
- # Update conversation history
330
- conversation.append({"role": "user", "content": user_input})
331
- conversation.append({"role": "assistant", "content": ai_response})
332
- user_session["conversation"] = conversation
333
- session_manager.update_session("default_user", user_session)
334
-
335
- # Add to message history
336
- st.session_state.messages.append({
337
- "role": "assistant",
338
- "content": ai_response,
339
- "timestamp": datetime.now().strftime("%H:%M:%S")
340
- })
341
- else:
342
- st.session_state.messages.append({
343
- "role": "assistant",
344
- "content": "Sorry, I couldn't process your request. Please try again.",
345
- "timestamp": datetime.now().strftime("%H:%M:%S")
346
- })
347
 
348
- except Exception as e:
349
- user_msg = translate_error(e)
350
- response_placeholder.error(f"โš ๏ธ {user_msg}")
 
 
 
 
 
 
351
  st.session_state.messages.append({
352
  "role": "assistant",
353
- "content": f"โš ๏ธ {user_msg}",
354
  "timestamp": datetime.now().strftime("%H:%M:%S")
355
  })
356
- finally:
357
- st.session_state.is_processing = False
358
- time.sleep(0.5) # Brief pause
359
- st.experimental_rerun()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
360
 
361
- with tab2:
 
 
 
 
362
  st.header("๐Ÿ”ฌ AI Behavior Evaluator")
363
  st.markdown("Run sample prompts to observe AI behavior.")
364
 
@@ -426,7 +426,7 @@ with tab2:
426
  except Exception as e:
427
  st.error(f"Evaluation failed: {translate_error(e)}")
428
 
429
- with tab3:
430
  st.header("๐Ÿ“Š Performance Reports")
431
  st.markdown("System performance metrics and usage analytics.")
432
 
@@ -510,3 +510,27 @@ with tab3:
510
  features.append("Weather Data")
511
 
512
  st.markdown(f"**Active Features:** {', '.join(features) if features else 'None'}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  if "hf_expert_requested" not in st.session_state:
45
  st.session_state.hf_expert_requested = False
46
 
47
+ # Sidebar layout redesign
48
+ with st.sidebar:
49
+ st.title("๐Ÿง  AI Life Coach")
50
+ st.markdown("Your personal AI-powered life development assistant")
51
+
52
+ # PRIMARY ACTIONS
53
+ st.subheader("๐Ÿ’ฌ Primary Actions")
54
+ model_options = {
55
+ "Mistral 7B (Local)": "mistral:latest",
56
+ "Llama 2 7B (Local)": "llama2:latest",
57
+ "OpenChat 3.5 (Local)": "openchat:latest"
58
+ }
59
+ selected_model_name = st.selectbox(
60
+ "Select Model",
61
+ options=list(model_options.keys()),
62
+ index=0,
63
+ key="sidebar_model_select"
64
+ )
65
+ st.session_state.selected_model = model_options[selected_model_name]
66
+
67
+ st.divider()
68
+
69
+ # CONFIGURATION
70
+ st.subheader("โš™๏ธ Configuration")
71
+ ngrok_url_input = st.text_input(
72
+ "Ollama Server URL",
73
+ value=st.session_state.ngrok_url_temp,
74
+ help="Enter your ngrok URL",
75
+ key="sidebar_ngrok_url"
76
+ )
77
+
78
+ if ngrok_url_input != st.session_state.ngrok_url_temp:
79
+ st.session_state.ngrok_url_temp = ngrok_url_input
80
+ st.success("โœ… URL updated!")
81
+
82
+ if st.button("๐Ÿ“ก Test Connection"):
83
+ try:
84
+ import requests
85
+ headers = {
86
+ "ngrok-skip-browser-warning": "true",
87
+ "User-Agent": "AI-Life-Coach-Test"
88
+ }
89
+ with st.spinner("Testing connection..."):
90
+ response = requests.get(
91
+ f"{ngrok_url_input}/api/tags",
92
+ headers=headers,
93
+ timeout=15
94
+ )
95
+ if response.status_code == 200:
96
+ st.success("โœ… Connection successful!")
97
+ else:
98
+ st.error(f"โŒ Failed: {response.status_code}")
99
+ except Exception as e:
100
+ st.error(f"โŒ Error: {str(e)[:50]}...")
101
+
102
+ if st.button("๐Ÿ—‘๏ธ Clear History"):
103
+ st.session_state.messages = []
104
+ st.success("History cleared!")
105
+
106
+ st.divider()
107
+
108
+ # ADVANCED FEATURES
109
+ with st.expander("๐Ÿ” Advanced Features", expanded=False):
110
+ st.subheader("๐Ÿ“Š System Monitor")
111
+ try:
112
+ from services.ollama_monitor import check_ollama_status
113
+ ollama_status = check_ollama_status()
114
+ if ollama_status.get("running"):
115
+ st.success("๐Ÿฆ™ Ollama: Running")
116
+ else:
117
+ st.warning("๐Ÿฆ™ Ollama: Not running")
118
+ except:
119
+ st.info("๐Ÿฆ™ Ollama: Unknown")
120
 
121
+ try:
122
+ from services.hf_endpoint_monitor import hf_monitor
123
+ hf_status = hf_monitor.check_endpoint_status()
124
+ if hf_status['available']:
125
+ st.success("๐Ÿค— HF: Available")
126
+ else:
127
+ st.warning("๐Ÿค— HF: Not available")
128
+ except:
129
+ st.info("๐Ÿค— HF: Unknown")
 
 
 
 
 
 
 
 
 
 
130
 
131
+ if check_redis_health():
132
+ st.success("๐Ÿ’พ Redis: Connected")
133
+ else:
134
+ st.error("๐Ÿ’พ Redis: Disconnected")
135
 
136
  st.divider()
137
 
138
+ st.subheader("๐Ÿค– HF Expert Analysis")
139
+ col1, col2 = st.columns([3, 1])
140
+ with col1:
141
+ st.markdown("""
142
+ **HF Expert Features:**
143
+ - Analyzes entire conversation history
144
+ - Performs web research when needed
145
+ - Provides deep insights and recommendations
146
+ - Acts as expert consultant in your conversation
147
+ """)
148
+ with col2:
149
+ if st.button("๐Ÿง  Activate HF Expert",
150
+ key="activate_hf_expert_sidebar",
151
+ help="Send conversation to HF endpoint for deep analysis",
152
+ use_container_width=True,
153
+ disabled=st.session_state.is_processing):
154
+ st.session_state.hf_expert_requested = True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
 
156
+ # Main interface
157
+ st.title("๐Ÿง  AI Life Coach")
158
+ st.markdown("Ask me anything about personal development, goal setting, or life advice!")
159
 
160
+ # Display messages
161
+ for message in st.session_state.messages:
162
+ with st.chat_message(message["role"]):
163
+ # Format HF expert messages differently
164
+ if message.get("source") == "hf_expert":
165
+ st.markdown("### ๐Ÿค– HF Expert Analysis")
166
+ st.markdown(message["content"])
167
+ else:
168
+ st.markdown(message["content"])
169
+ if "timestamp" in message:
170
+ st.caption(f"๐Ÿ•’ {message['timestamp']}")
171
 
172
+ # Manual HF Analysis Section
173
+ if st.session_state.messages and len(st.session_state.messages) > 0:
174
+ st.divider()
175
+
176
+ # HF Expert Section
177
+ with st.expander("๐Ÿค– HF Expert Analysis", expanded=False):
178
+ st.subheader("Deep Conversation Analysis")
179
 
180
+ col1, col2 = st.columns([3, 1])
181
+ with col1:
182
+ st.markdown("""
183
+ **HF Expert Features:**
184
+ - Analyzes entire conversation history
185
+ - Performs web research when needed
186
+ - Provides deep insights and recommendations
187
+ - Acts as expert consultant in your conversation
188
+ """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
 
190
+ # Show conversation preview
191
+ st.markdown("**Conversation Preview for HF Expert:**")
192
+ st.markdown("---")
193
+ for i, msg in enumerate(st.session_state.messages[-5:]): # Last 5 messages
194
+ role = "๐Ÿ‘ค You" if msg["role"] == "user" else "๐Ÿค– Assistant"
195
+ st.markdown(f"**{role}:** {msg['content'][:100]}{'...' if len(msg['content']) > 100 else ''}")
196
+ st.markdown("---")
197
+
198
+ with col2:
199
+ if st.button("๐Ÿง  Activate HF Expert",
200
+ key="activate_hf_expert",
201
+ help="Send conversation to HF endpoint for deep analysis",
202
+ use_container_width=True,
203
+ disabled=st.session_state.is_processing):
204
+ st.session_state.hf_expert_requested = True
205
+
206
+ # Show HF expert analysis when requested
207
+ if st.session_state.get("hf_expert_requested", False):
208
+ with st.spinner("๐Ÿง  HF Expert analyzing conversation..."):
209
+ try:
210
+ # Get conversation history
211
+ user_session = session_manager.get_session("default_user")
212
+ conversation_history = user_session.get("conversation", [])
213
+
214
+ # Show what HF expert sees
215
+ with st.expander("๐Ÿ“‹ HF Expert Input", expanded=False):
216
+ st.markdown("**Conversation History Sent to HF Expert:**")
217
+ for i, msg in enumerate(conversation_history[-10:]): # Last 10 messages
218
+ st.markdown(f"**{msg['role'].capitalize()}:** {msg['content'][:100]}{'...' if len(msg['content']) > 100 else ''}")
219
+
220
+ # Request HF analysis
221
+ hf_analysis = coordinator.manual_hf_analysis(
222
+ "default_user",
223
+ conversation_history
224
+ )
225
+
226
+ if hf_analysis:
227
+ # Display HF expert response with clear indication
228
+ with st.chat_message("assistant"):
229
+ st.markdown("### ๐Ÿค– HF Expert Analysis")
230
+ st.markdown(hf_analysis)
231
 
232
+ # Add research/web search decisions
233
+ research_needs = coordinator.determine_web_search_needs(conversation_history)
234
+ if research_needs["needs_search"]:
235
+ st.info(f"๐Ÿ” **Research Needed:** {research_needs['reasoning']}")
236
+ if st.button("๐Ÿ”Ž Perform Web Research", key="web_research_button"):
237
+ # Perform web search
238
+ with st.spinner("๐Ÿ”Ž Searching for current information..."):
239
+ # Add web search logic here
240
+ st.success("โœ… Web research completed!")
241
 
242
+ # Add to message history with HF expert tag
243
+ st.session_state.messages.append({
244
+ "role": "assistant",
245
+ "content": hf_analysis,
246
+ "timestamp": datetime.now().strftime("%H:%M:%S"),
247
+ "source": "hf_expert",
248
+ "research_needs": research_needs
249
+ })
250
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
  st.session_state.hf_expert_requested = False
252
+
253
+ except Exception as e:
254
+ user_msg = translate_error(e)
255
+ st.error(f"โŒ HF Expert analysis failed: {user_msg}")
256
+ st.session_state.hf_expert_requested = False
257
 
258
+ # Chat input - FIXED VERSION (moved outside of tabs)
259
+ user_input = st.chat_input("Type your message here...", disabled=st.session_state.is_processing)
260
 
261
+ # Process message when received
262
+ if user_input and not st.session_state.is_processing:
263
+ st.session_state.is_processing = True
264
+
265
+ # Display user message
266
+ with st.chat_message("user"):
267
+ st.markdown(user_input)
268
+
269
+ st.session_state.messages.append({
270
+ "role": "user",
271
+ "content": user_input,
272
+ "timestamp": datetime.now().strftime("%H:%M:%S")
273
+ })
274
+
275
+ # Process AI response
276
+ with st.chat_message("assistant"):
277
+ response_placeholder = st.empty()
278
+ status_placeholder = st.empty()
279
 
280
+ try:
281
+ # Get conversation history
282
+ user_session = session_manager.get_session("default_user")
283
+ conversation = user_session.get("conversation", [])
284
+ conversation_history = conversation[-5:] # Last 5 messages
285
+ conversation_history.append({"role": "user", "content": user_input})
286
+
287
+ # Try Ollama with proper error handling
288
+ status_placeholder.info(PROCESSING_STAGES["ollama"])
289
+ ai_response = None
290
 
291
  try:
292
+ ai_response = send_to_ollama(
293
+ user_input,
294
+ conversation_history,
295
+ st.session_state.ngrok_url_temp,
296
+ st.session_state.selected_model
297
+ )
 
 
 
298
 
299
+ if ai_response:
300
+ response_placeholder.markdown(ai_response)
301
+ status_placeholder.success("โœ… Response received!")
302
+ else:
303
+ status_placeholder.warning("โš ๏ธ Empty response from Ollama")
304
+
305
+ except Exception as ollama_error:
306
+ user_msg = translate_error(ollama_error)
307
+ status_placeholder.error(f"โš ๏ธ {user_msg}")
308
+
309
+ # Fallback to HF if available
310
+ if config.hf_token and not ai_response:
311
+ status_placeholder.info(PROCESSING_STAGES["hf_init"])
312
  try:
313
+ ai_response = send_to_hf(user_input, conversation_history)
 
 
 
 
 
 
314
  if ai_response:
315
  response_placeholder.markdown(ai_response)
316
+ status_placeholder.success("โœ… HF response received!")
317
  else:
318
+ status_placeholder.error("โŒ No response from HF")
319
+ except Exception as hf_error:
320
+ user_msg = translate_error(hf_error)
 
321
  status_placeholder.error(f"โš ๏ธ {user_msg}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
322
 
323
+ # Save response if successful
324
+ if ai_response:
325
+ # Update conversation history
326
+ conversation.append({"role": "user", "content": user_input})
327
+ conversation.append({"role": "assistant", "content": ai_response})
328
+ user_session["conversation"] = conversation
329
+ session_manager.update_session("default_user", user_session)
330
+
331
+ # Add to message history
332
  st.session_state.messages.append({
333
  "role": "assistant",
334
+ "content": ai_response,
335
  "timestamp": datetime.now().strftime("%H:%M:%S")
336
  })
337
+ else:
338
+ st.session_state.messages.append({
339
+ "role": "assistant",
340
+ "content": "Sorry, I couldn't process your request. Please try again.",
341
+ "timestamp": datetime.now().strftime("%H:%M:%S")
342
+ })
343
+
344
+ except Exception as e:
345
+ user_msg = translate_error(e)
346
+ response_placeholder.error(f"โš ๏ธ {user_msg}")
347
+ st.session_state.messages.append({
348
+ "role": "assistant",
349
+ "content": f"โš ๏ธ {user_msg}",
350
+ "timestamp": datetime.now().strftime("%H:%M:%S")
351
+ })
352
+ finally:
353
+ st.session_state.is_processing = False
354
+ time.sleep(0.5) # Brief pause
355
+ st.experimental_rerun()
356
 
357
+ # Add evaluation dashboard tab (separate from chat interface)
358
+ st.divider()
359
+ tab1, tab2, tab3 = st.tabs(["๐Ÿ”ฌ Evaluate AI", "๐Ÿ“Š Reports", "โ„น๏ธ About"])
360
+
361
+ with tab1:
362
  st.header("๐Ÿ”ฌ AI Behavior Evaluator")
363
  st.markdown("Run sample prompts to observe AI behavior.")
364
 
 
426
  except Exception as e:
427
  st.error(f"Evaluation failed: {translate_error(e)}")
428
 
429
+ with tab2:
430
  st.header("๐Ÿ“Š Performance Reports")
431
  st.markdown("System performance metrics and usage analytics.")
432
 
 
510
  features.append("Weather Data")
511
 
512
  st.markdown(f"**Active Features:** {', '.join(features) if features else 'None'}")
513
+
514
+ with tab3:
515
+ st.header("โ„น๏ธ About AI Life Coach")
516
+ st.markdown("""
517
+ The AI Life Coach is a sophisticated conversational AI system with the following capabilities:
518
+
519
+ ### ๐Ÿง  Core Features
520
+ - **Multi-model coordination**: Combines local Ollama models with cloud-based Hugging Face endpoints
521
+ - **Live web search**: Integrates with Tavily API for current information
522
+ - **Academic research**: Accesses peer-reviewed papers via Semantic Scholar
523
+ - **Persistent memory**: Uses Redis for conversation history storage
524
+ - **Hierarchical reasoning**: Fast local responses with deep cloud analysis
525
+
526
+ ### ๐Ÿ› ๏ธ Technical Architecture
527
+ - **Primary model**: Ollama (local processing for fast responses)
528
+ - **Secondary model**: Hugging Face Inference API (deep analysis)
529
+ - **External data**: Web search, weather, and academic papers
530
+ - **Memory system**: Redis-based session management
531
+
532
+ ### ๐Ÿ“Š Evaluation Tools
533
+ - Behavior testing with sample prompts
534
+ - Performance metrics and analytics
535
+ - Research paper integration for scientific topics
536
+ """)