rdune71 commited on
Commit
22e5f83
Β·
1 Parent(s): bed2d0a

Implement Cosmic Cascade Response Mode with three-stage AI flow

Browse files
Files changed (3) hide show
  1. app.py +104 -116
  2. core/coordinator.py +154 -155
  3. core/personality.py +9 -9
app.py CHANGED
@@ -7,7 +7,6 @@ import asyncio
7
  from datetime import datetime
8
  from pathlib import Path
9
  sys.path.append(str(Path(__file__).parent))
10
-
11
  from utils.config import config
12
  from core.llm import send_to_ollama, send_to_hf
13
  from core.session import session_manager
@@ -67,7 +66,7 @@ with st.sidebar:
67
  )
68
  st.session_state.selected_model = model_options[selected_model_name]
69
 
70
- # Toggle for cosmic mode using checkbox (since toggle doesn't exist in older versions)
71
  st.session_state.cosmic_mode = st.checkbox("Enable Cosmic Mode", value=st.session_state.cosmic_mode)
72
 
73
  st.divider()
@@ -84,7 +83,7 @@ with st.sidebar:
84
  if ngrok_url_input != st.session_state.ngrok_url_temp:
85
  st.session_state.ngrok_url_temp = ngrok_url_input
86
  st.success("βœ… URL updated!")
87
-
88
  if st.button("πŸ“‘ Test Connection"):
89
  try:
90
  import requests
@@ -104,11 +103,11 @@ with st.sidebar:
104
  st.error(f"❌ Failed: {response.status_code}")
105
  except Exception as e:
106
  st.error(f"❌ Error: {str(e)[:50]}...")
107
-
108
  if st.button("πŸ—‘οΈ Clear History"):
109
  st.session_state.messages = []
110
  st.success("History cleared!")
111
-
112
  st.divider()
113
 
114
  # SYSTEM STATUS
@@ -123,7 +122,7 @@ with st.sidebar:
123
  st.warning("πŸ¦™ Ollama: Not running")
124
  except:
125
  st.info("πŸ¦™ Ollama: Unknown")
126
-
127
  try:
128
  hf_status = hf_monitor.check_endpoint_status()
129
  if hf_status['available']:
@@ -135,42 +134,42 @@ with st.sidebar:
135
  st.info("πŸ€— HF: Not configured")
136
  except:
137
  st.info("πŸ€— HF: Unknown")
138
-
139
  if check_redis_health():
140
  st.success("πŸ’Ύ Redis: Connected")
141
  else:
142
  st.error("πŸ’Ύ Redis: Disconnected")
 
 
 
 
 
 
 
 
 
 
 
143
 
144
- st.divider()
145
-
146
- # NASA Context Display
147
- if st.session_state.nasa_data.get("apod"):
148
- apod = st.session_state.nasa_data["apod"]
149
- st.subheader("🌌 Cosmic Context")
150
- if apod.get("media_type") == "image" and apod.get("url"):
151
- st.image(apod["url"], caption=apod.get("title", "Astronomy Picture of the Day"), width=200)
152
- st.markdown(f"**{apod.get('title', 'Cosmic Phenomenon')}**")
153
- st.caption(apod.get("explanation", "")[:100] + "..." if len(apod.get("explanation", "")) > 100 else apod.get("explanation", ""))
154
-
155
- st.divider()
156
- st.subheader("πŸ› Debug Info")
157
- # Show current configuration
158
- st.markdown(f"**Environment:** {'HF Space' if config.is_hf_space else 'Local'}")
159
- st.markdown(f"**Model:** {st.session_state.selected_model}")
160
- st.markdown(f"**Cosmic Mode:** {'Enabled' if st.session_state.cosmic_mode else 'Disabled'}")
161
-
162
- # Show active features
163
- features = []
164
- if config.hf_token:
165
- features.append("HF Expert")
166
- if os.getenv("TAVILY_API_KEY"):
167
- features.append("Web Search")
168
- if config.openweather_api_key:
169
- features.append("Weather")
170
- if config.nasa_api_key:
171
- features.append("Space Data")
172
-
173
- st.markdown(f"**Active Features:** {', '.join(features) if features else 'None'}")
174
 
175
  # Main interface
176
  st.title("🐱 CosmicCat AI Assistant")
@@ -203,7 +202,6 @@ def render_message(role, content, source=None, timestamp=None):
203
  st.markdown(f"### 🐱 Cosmic Kitten Story:")
204
  else:
205
  st.markdown(f"### {source}")
206
-
207
  st.markdown(content)
208
  if timestamp:
209
  st.caption(f"πŸ•’ {timestamp}")
@@ -211,9 +209,9 @@ def render_message(role, content, source=None, timestamp=None):
211
  # Display messages
212
  for message in st.session_state.messages:
213
  render_message(
214
- message["role"],
215
- message["content"],
216
- message.get("source"),
217
  message.get("timestamp")
218
  )
219
 
@@ -222,7 +220,6 @@ def validate_user_input(text):
222
  """Validate and sanitize user input"""
223
  if not text or not text.strip():
224
  return False, "Input cannot be empty"
225
-
226
  if len(text) > 1000:
227
  return False, "Input too long (max 1000 characters)"
228
 
@@ -249,7 +246,7 @@ if user_input and not st.session_state.is_processing:
249
  # Display user message
250
  with st.chat_message("user"):
251
  st.markdown(validated_input)
252
-
253
  # Add to message history - ensure proper format
254
  st.session_state.messages.append({
255
  "role": "user",
@@ -283,7 +280,7 @@ if user_input and not st.session_state.is_processing:
283
  # Stage 1: Local Ollama Response
284
  status_placeholder.info("🐱 Cosmic Kitten Responding...")
285
  local_response = send_to_ollama(
286
- validated_input,
287
  conversation_history,
288
  st.session_state.ngrok_url_temp,
289
  st.session_state.selected_model
@@ -292,14 +289,13 @@ if user_input and not st.session_state.is_processing:
292
  if local_response:
293
  with st.chat_message("assistant"):
294
  st.markdown(f"### 🐱 Cosmic Kitten Says:\n{local_response}")
295
-
296
- st.session_state.messages.append({
297
- "role": "assistant",
298
- "content": local_response,
299
- "source": "local_kitty",
300
- "timestamp": datetime.now().strftime("%H:%M:%S")
301
- })
302
-
303
  # Stage 2: HF Endpoint Analysis
304
  status_placeholder.info("πŸ›°οΈ Beaming Query to Orbital Station...")
305
  if config.hf_token:
@@ -307,21 +303,22 @@ if user_input and not st.session_state.is_processing:
307
  hf_status = hf_monitor.check_endpoint_status()
308
  if not hf_status['available']:
309
  status_placeholder.info(personality.get_initializing_message())
310
-
311
  hf_response = send_to_hf(validated_input, conversation_history)
 
312
  if hf_response:
313
  with st.chat_message("assistant"):
314
  st.markdown(f"### πŸ›°οΈ Orbital Station Reports:\n{hf_response}")
315
-
316
- st.session_state.messages.append({
317
- "role": "assistant",
318
- "content": hf_response,
319
- "source": "orbital_station",
320
- "timestamp": datetime.now().strftime("%H:%M:%S")
321
- })
322
-
323
  # Stage 3: Local Synthesis
324
  status_placeholder.info("🐱 Cosmic Kitten Synthesizing Wisdom...")
 
325
  # Update history with both responses
326
  synthesis_history = conversation_history.copy()
327
  synthesis_history.extend([
@@ -339,16 +336,15 @@ if user_input and not st.session_state.is_processing:
339
  if synthesis:
340
  with st.chat_message("assistant"):
341
  st.markdown(f"### 🌟 Final Cosmic Summary:\n{synthesis}")
342
-
343
- st.session_state.messages.append({
344
- "role": "assistant",
345
- "content": synthesis,
346
- "source": "cosmic_summary",
347
- "timestamp": datetime.now().strftime("%H:%M:%S")
348
- })
349
-
350
  status_placeholder.success("✨ Cosmic Cascade Complete!")
351
-
352
  except Exception as e:
353
  error_msg = f"🌌 Cosmic disturbance: {str(e)}"
354
  st.error(error_msg)
@@ -377,30 +373,33 @@ if user_input and not st.session_state.is_processing:
377
  status_placeholder.success("βœ… Response received!")
378
  else:
379
  status_placeholder.warning("⚠️ Empty response from Ollama")
380
-
381
  except Exception as ollama_error:
382
  user_msg = translate_error(ollama_error)
383
  status_placeholder.error(f"⚠️ {user_msg}")
384
-
385
- # Fallback to HF if available
386
- if config.hf_token and not ai_response:
387
- status_placeholder.info("⚑ Initializing HF Endpoint (2–4 minutes)...")
388
- try:
389
- # Check HF status first
390
- hf_status = hf_monitor.check_endpoint_status()
391
- if not hf_status['available']:
392
- status_placeholder.info(personality.get_initializing_message())
393
 
394
- ai_response = send_to_hf(validated_input, conversation_history)
395
- if ai_response:
396
- response_placeholder.markdown(ai_response)
397
- status_placeholder.success("βœ… HF response received!")
398
- else:
399
- status_placeholder.error("❌ No response from HF")
400
- except Exception as hf_error:
401
- user_msg = translate_error(hf_error)
402
- status_placeholder.error(f"⚠️ {user_msg}")
403
-
 
 
 
 
 
 
 
 
404
  # Save response if successful
405
  if ai_response:
406
  # Update conversation history
@@ -431,7 +430,7 @@ if user_input and not st.session_state.is_processing:
431
  "content": "Sorry, I couldn't process your request. Please try again.",
432
  "timestamp": datetime.now().strftime("%H:%M:%S")
433
  })
434
-
435
  except Exception as e:
436
  user_msg = translate_error(e)
437
  response_placeholder.error(f"⚠️ {user_msg}")
@@ -440,7 +439,7 @@ if user_input and not st.session_state.is_processing:
440
  "content": f"⚠️ {user_msg}",
441
  "timestamp": datetime.now().strftime("%H:%M:%S")
442
  })
443
-
444
  # Moved finally block to proper location
445
  st.session_state.is_processing = False
446
  time.sleep(0.5) # Brief pause
@@ -464,7 +463,6 @@ with tab1:
464
 
465
  selected_prompt = st.selectbox("Choose a test prompt:", eval_prompts)
466
  custom_prompt = st.text_input("Or enter your own:", "")
467
-
468
  final_prompt = custom_prompt or selected_prompt
469
 
470
  if st.button("Evaluate"):
@@ -479,11 +477,9 @@ with tab1:
479
  try:
480
  ai_response = send_to_ollama(final_prompt, history, st.session_state.ngrok_url_temp, st.session_state.selected_model)
481
  duration = round(time.time() - start_time, 2)
482
-
483
  st.success(f"βœ… Response generated in {duration}s")
484
  st.markdown("**Response:**")
485
  st.write(ai_response)
486
-
487
  st.markdown("**Analysis Tags:**")
488
  tags = []
489
  if "today" in final_prompt.lower() or "date" in final_prompt.lower():
@@ -493,7 +489,6 @@ with tab1:
493
  if any(word in final_prompt.lower() for word in ["vitamin", "drug", "metformin", "CRISPR"]):
494
  tags.append("🧬 Scientific Knowledge")
495
  st.write(", ".join(tags) if tags else "General Knowledge")
496
-
497
  except Exception as e:
498
  st.error(f"Evaluation failed: {translate_error(e)}")
499
 
@@ -504,7 +499,6 @@ with tab2:
504
  # System status
505
  st.subheader("System Status")
506
  col1, col2, col3 = st.columns(3)
507
-
508
  with col1:
509
  try:
510
  from services.ollama_monitor import check_ollama_status
@@ -515,7 +509,6 @@ with tab2:
515
  st.warning("πŸ¦™ Ollama: Not running")
516
  except:
517
  st.info("πŸ¦™ Ollama: Unknown")
518
-
519
  with col2:
520
  try:
521
  hf_status = hf_monitor.check_endpoint_status()
@@ -528,13 +521,12 @@ with tab2:
528
  st.info("πŸ€— HF: Not configured")
529
  except:
530
  st.info("πŸ€— HF: Unknown")
531
-
532
  with col3:
533
  if check_redis_health():
534
  st.success("πŸ’Ύ Redis: Connected")
535
  else:
536
  st.error("πŸ’Ύ Redis: Disconnected")
537
-
538
  # Session statistics
539
  st.subheader("Session Statistics")
540
  try:
@@ -551,7 +543,7 @@ with tab2:
551
  st.info("No coordination statistics available yet.")
552
  except Exception as e:
553
  st.warning(f"Could not load session statistics: {translate_error(e)}")
554
-
555
  # Recent activity
556
  st.subheader("Recent Activity")
557
  try:
@@ -565,7 +557,7 @@ with tab2:
565
  st.info("No recent activity recorded.")
566
  except Exception as e:
567
  st.warning(f"Could not load recent activity: {translate_error(e)}")
568
-
569
  # Configuration summary
570
  st.subheader("Configuration Summary")
571
  st.markdown(f"**Environment:** {'HF Space' if config.is_hf_space else 'Local'}")
@@ -584,7 +576,6 @@ with tab2:
584
  features.append("Weather Data")
585
  if config.nasa_api_key:
586
  features.append("Space Data")
587
-
588
  st.markdown(f"**Active Features:** {', '.join(features) if features else 'None'}")
589
 
590
  # Conversation Analytics
@@ -592,7 +583,6 @@ with tab2:
592
  try:
593
  user_session = session_manager.get_session("default_user")
594
  conversation = user_session.get("conversation", [])
595
-
596
  if conversation:
597
  # Analyze conversation patterns
598
  user_messages = [msg for msg in conversation if msg["role"] == "user"]
@@ -601,9 +591,9 @@ with tab2:
601
  col1, col2, col3 = st.columns(3)
602
  col1.metric("Total Exchanges", len(user_messages))
603
  col2.metric("Avg Response Length",
604
- round(sum(len(msg.get("content", "")) for msg in ai_messages) / len(ai_messages)) if ai_messages else 0)
605
- col3.metric("Topics Discussed", len(set(["life", "goal", "health", "career"]) &
606
- set(" ".join([msg.get("content", "") for msg in conversation]).lower().split())))
607
 
608
  # Show most common words/topics
609
  all_text = " ".join([msg.get("content", "") for msg in conversation]).lower()
@@ -613,7 +603,6 @@ with tab2:
613
  st.markdown(f"**Detected Topics:** {', '.join(relevant_topics)}")
614
  else:
615
  st.info("No conversation data available yet.")
616
-
617
  except Exception as e:
618
  st.warning(f"Could not analyze conversation: {translate_error(e)}")
619
 
@@ -632,7 +621,7 @@ with tab3:
632
  When enabled, the AI follows a three-stage response pattern:
633
  1. **🐱 Cosmic Kitten Response**: Immediate local processing
634
  2. **πŸ›°οΈ Orbital Station Analysis**: Deep cloud-based analysis
635
- 3. **🌟 Final Synthesis**: Unified response combining both perspectives
636
 
637
  ### πŸ› οΈ Technical Architecture
638
  - **Primary model**: Ollama (local processing for fast responses)
@@ -650,10 +639,9 @@ if user_input and user_input.lower().strip() in ["hello", "hi", "hey"]:
650
  with st.chat_message("assistant"):
651
  story = personality.get_space_story()
652
  st.markdown(f"### 🐱 Cosmic Kitten Story:\n\n{story}")
653
-
654
- st.session_state.messages.append({
655
- "role": "assistant",
656
- "content": story,
657
- "source": "space_story",
658
- "timestamp": datetime.now().strftime("%H:%M:%S")
659
- })
 
7
  from datetime import datetime
8
  from pathlib import Path
9
  sys.path.append(str(Path(__file__).parent))
 
10
  from utils.config import config
11
  from core.llm import send_to_ollama, send_to_hf
12
  from core.session import session_manager
 
66
  )
67
  st.session_state.selected_model = model_options[selected_model_name]
68
 
69
+ # Toggle for cosmic mode using checkbox
70
  st.session_state.cosmic_mode = st.checkbox("Enable Cosmic Mode", value=st.session_state.cosmic_mode)
71
 
72
  st.divider()
 
83
  if ngrok_url_input != st.session_state.ngrok_url_temp:
84
  st.session_state.ngrok_url_temp = ngrok_url_input
85
  st.success("βœ… URL updated!")
86
+
87
  if st.button("πŸ“‘ Test Connection"):
88
  try:
89
  import requests
 
103
  st.error(f"❌ Failed: {response.status_code}")
104
  except Exception as e:
105
  st.error(f"❌ Error: {str(e)[:50]}...")
106
+
107
  if st.button("πŸ—‘οΈ Clear History"):
108
  st.session_state.messages = []
109
  st.success("History cleared!")
110
+
111
  st.divider()
112
 
113
  # SYSTEM STATUS
 
122
  st.warning("πŸ¦™ Ollama: Not running")
123
  except:
124
  st.info("πŸ¦™ Ollama: Unknown")
125
+
126
  try:
127
  hf_status = hf_monitor.check_endpoint_status()
128
  if hf_status['available']:
 
134
  st.info("πŸ€— HF: Not configured")
135
  except:
136
  st.info("πŸ€— HF: Unknown")
137
+
138
  if check_redis_health():
139
  st.success("πŸ’Ύ Redis: Connected")
140
  else:
141
  st.error("πŸ’Ύ Redis: Disconnected")
142
+
143
+ st.divider()
144
+
145
+ # NASA Context Display
146
+ if st.session_state.nasa_data.get("apod"):
147
+ apod = st.session_state.nasa_data["apod"]
148
+ st.subheader("🌌 Cosmic Context")
149
+ if apod.get("media_type") == "image" and apod.get("url"):
150
+ st.image(apod["url"], caption=apod.get("title", "Astronomy Picture of the Day"), width=200)
151
+ st.markdown(f"{apod.get('title', 'Cosmic Phenomenon')}")
152
+ st.caption(apod.get("explanation", "")[:100] + "..." if len(apod.get("explanation", "")) > 100 else apod.get("explanation", ""))
153
 
154
+ st.divider()
155
+
156
+ st.subheader("πŸ› Debug Info")
157
+ # Show current configuration
158
+ st.markdown(f"Environment: {'HF Space' if config.is_hf_space else 'Local'}")
159
+ st.markdown(f"Model: {st.session_state.selected_model}")
160
+ st.markdown(f"Cosmic Mode: {'Enabled' if st.session_state.cosmic_mode else 'Disabled'}")
161
+
162
+ # Show active features
163
+ features = []
164
+ if config.hf_token:
165
+ features.append("HF Expert")
166
+ if os.getenv("TAVILY_API_KEY"):
167
+ features.append("Web Search")
168
+ if config.openweather_api_key:
169
+ features.append("Weather")
170
+ if config.nasa_api_key:
171
+ features.append("Space Data")
172
+ st.markdown(f"Active Features: {', '.join(features) if features else 'None'}")
 
 
 
 
 
 
 
 
 
 
 
173
 
174
  # Main interface
175
  st.title("🐱 CosmicCat AI Assistant")
 
202
  st.markdown(f"### 🐱 Cosmic Kitten Story:")
203
  else:
204
  st.markdown(f"### {source}")
 
205
  st.markdown(content)
206
  if timestamp:
207
  st.caption(f"πŸ•’ {timestamp}")
 
209
  # Display messages
210
  for message in st.session_state.messages:
211
  render_message(
212
+ message["role"],
213
+ message["content"],
214
+ message.get("source"),
215
  message.get("timestamp")
216
  )
217
 
 
220
  """Validate and sanitize user input"""
221
  if not text or not text.strip():
222
  return False, "Input cannot be empty"
 
223
  if len(text) > 1000:
224
  return False, "Input too long (max 1000 characters)"
225
 
 
246
  # Display user message
247
  with st.chat_message("user"):
248
  st.markdown(validated_input)
249
+
250
  # Add to message history - ensure proper format
251
  st.session_state.messages.append({
252
  "role": "user",
 
280
  # Stage 1: Local Ollama Response
281
  status_placeholder.info("🐱 Cosmic Kitten Responding...")
282
  local_response = send_to_ollama(
283
+ validated_input,
284
  conversation_history,
285
  st.session_state.ngrok_url_temp,
286
  st.session_state.selected_model
 
289
  if local_response:
290
  with st.chat_message("assistant"):
291
  st.markdown(f"### 🐱 Cosmic Kitten Says:\n{local_response}")
292
+ st.session_state.messages.append({
293
+ "role": "assistant",
294
+ "content": local_response,
295
+ "source": "local_kitty",
296
+ "timestamp": datetime.now().strftime("%H:%M:%S")
297
+ })
298
+
 
299
  # Stage 2: HF Endpoint Analysis
300
  status_placeholder.info("πŸ›°οΈ Beaming Query to Orbital Station...")
301
  if config.hf_token:
 
303
  hf_status = hf_monitor.check_endpoint_status()
304
  if not hf_status['available']:
305
  status_placeholder.info(personality.get_initializing_message())
306
+
307
  hf_response = send_to_hf(validated_input, conversation_history)
308
+
309
  if hf_response:
310
  with st.chat_message("assistant"):
311
  st.markdown(f"### πŸ›°οΈ Orbital Station Reports:\n{hf_response}")
312
+ st.session_state.messages.append({
313
+ "role": "assistant",
314
+ "content": hf_response,
315
+ "source": "orbital_station",
316
+ "timestamp": datetime.now().strftime("%H:%M:%S")
317
+ })
318
+
 
319
  # Stage 3: Local Synthesis
320
  status_placeholder.info("🐱 Cosmic Kitten Synthesizing Wisdom...")
321
+
322
  # Update history with both responses
323
  synthesis_history = conversation_history.copy()
324
  synthesis_history.extend([
 
336
  if synthesis:
337
  with st.chat_message("assistant"):
338
  st.markdown(f"### 🌟 Final Cosmic Summary:\n{synthesis}")
339
+ st.session_state.messages.append({
340
+ "role": "assistant",
341
+ "content": synthesis,
342
+ "source": "cosmic_summary",
343
+ "timestamp": datetime.now().strftime("%H:%M:%S")
344
+ })
345
+
 
346
  status_placeholder.success("✨ Cosmic Cascade Complete!")
347
+
348
  except Exception as e:
349
  error_msg = f"🌌 Cosmic disturbance: {str(e)}"
350
  st.error(error_msg)
 
373
  status_placeholder.success("βœ… Response received!")
374
  else:
375
  status_placeholder.warning("⚠️ Empty response from Ollama")
376
+
377
  except Exception as ollama_error:
378
  user_msg = translate_error(ollama_error)
379
  status_placeholder.error(f"⚠️ {user_msg}")
380
+
381
+ # Fallback to HF if available
382
+ if config.hf_token and not ai_response:
383
+ status_placeholder.info("⚑ Initializing HF Endpoint (2–4 minutes)...")
 
 
 
 
 
384
 
385
+ try:
386
+ # Check HF status first
387
+ hf_status = hf_monitor.check_endpoint_status()
388
+ if not hf_status['available']:
389
+ status_placeholder.info(personality.get_initializing_message())
390
+
391
+ ai_response = send_to_hf(validated_input, conversation_history)
392
+
393
+ if ai_response:
394
+ response_placeholder.markdown(ai_response)
395
+ status_placeholder.success("βœ… HF response received!")
396
+ else:
397
+ status_placeholder.error("❌ No response from HF")
398
+
399
+ except Exception as hf_error:
400
+ user_msg = translate_error(hf_error)
401
+ status_placeholder.error(f"⚠️ {user_msg}")
402
+
403
  # Save response if successful
404
  if ai_response:
405
  # Update conversation history
 
430
  "content": "Sorry, I couldn't process your request. Please try again.",
431
  "timestamp": datetime.now().strftime("%H:%M:%S")
432
  })
433
+
434
  except Exception as e:
435
  user_msg = translate_error(e)
436
  response_placeholder.error(f"⚠️ {user_msg}")
 
439
  "content": f"⚠️ {user_msg}",
440
  "timestamp": datetime.now().strftime("%H:%M:%S")
441
  })
442
+
443
  # Moved finally block to proper location
444
  st.session_state.is_processing = False
445
  time.sleep(0.5) # Brief pause
 
463
 
464
  selected_prompt = st.selectbox("Choose a test prompt:", eval_prompts)
465
  custom_prompt = st.text_input("Or enter your own:", "")
 
466
  final_prompt = custom_prompt or selected_prompt
467
 
468
  if st.button("Evaluate"):
 
477
  try:
478
  ai_response = send_to_ollama(final_prompt, history, st.session_state.ngrok_url_temp, st.session_state.selected_model)
479
  duration = round(time.time() - start_time, 2)
 
480
  st.success(f"βœ… Response generated in {duration}s")
481
  st.markdown("**Response:**")
482
  st.write(ai_response)
 
483
  st.markdown("**Analysis Tags:**")
484
  tags = []
485
  if "today" in final_prompt.lower() or "date" in final_prompt.lower():
 
489
  if any(word in final_prompt.lower() for word in ["vitamin", "drug", "metformin", "CRISPR"]):
490
  tags.append("🧬 Scientific Knowledge")
491
  st.write(", ".join(tags) if tags else "General Knowledge")
 
492
  except Exception as e:
493
  st.error(f"Evaluation failed: {translate_error(e)}")
494
 
 
499
  # System status
500
  st.subheader("System Status")
501
  col1, col2, col3 = st.columns(3)
 
502
  with col1:
503
  try:
504
  from services.ollama_monitor import check_ollama_status
 
509
  st.warning("πŸ¦™ Ollama: Not running")
510
  except:
511
  st.info("πŸ¦™ Ollama: Unknown")
 
512
  with col2:
513
  try:
514
  hf_status = hf_monitor.check_endpoint_status()
 
521
  st.info("πŸ€— HF: Not configured")
522
  except:
523
  st.info("πŸ€— HF: Unknown")
 
524
  with col3:
525
  if check_redis_health():
526
  st.success("πŸ’Ύ Redis: Connected")
527
  else:
528
  st.error("πŸ’Ύ Redis: Disconnected")
529
+
530
  # Session statistics
531
  st.subheader("Session Statistics")
532
  try:
 
543
  st.info("No coordination statistics available yet.")
544
  except Exception as e:
545
  st.warning(f"Could not load session statistics: {translate_error(e)}")
546
+
547
  # Recent activity
548
  st.subheader("Recent Activity")
549
  try:
 
557
  st.info("No recent activity recorded.")
558
  except Exception as e:
559
  st.warning(f"Could not load recent activity: {translate_error(e)}")
560
+
561
  # Configuration summary
562
  st.subheader("Configuration Summary")
563
  st.markdown(f"**Environment:** {'HF Space' if config.is_hf_space else 'Local'}")
 
576
  features.append("Weather Data")
577
  if config.nasa_api_key:
578
  features.append("Space Data")
 
579
  st.markdown(f"**Active Features:** {', '.join(features) if features else 'None'}")
580
 
581
  # Conversation Analytics
 
583
  try:
584
  user_session = session_manager.get_session("default_user")
585
  conversation = user_session.get("conversation", [])
 
586
  if conversation:
587
  # Analyze conversation patterns
588
  user_messages = [msg for msg in conversation if msg["role"] == "user"]
 
591
  col1, col2, col3 = st.columns(3)
592
  col1.metric("Total Exchanges", len(user_messages))
593
  col2.metric("Avg Response Length",
594
+ round(sum(len(msg.get("content", "")) for msg in ai_messages) / len(ai_messages)) if ai_messages else 0)
595
+ col3.metric("Topics Discussed",
596
+ len(set(["life", "goal", "health", "career"]) & set(" ".join([msg.get("content", "") for msg in conversation]).lower().split())))
597
 
598
  # Show most common words/topics
599
  all_text = " ".join([msg.get("content", "") for msg in conversation]).lower()
 
603
  st.markdown(f"**Detected Topics:** {', '.join(relevant_topics)}")
604
  else:
605
  st.info("No conversation data available yet.")
 
606
  except Exception as e:
607
  st.warning(f"Could not analyze conversation: {translate_error(e)}")
608
 
 
621
  When enabled, the AI follows a three-stage response pattern:
622
  1. **🐱 Cosmic Kitten Response**: Immediate local processing
623
  2. **πŸ›°οΈ Orbital Station Analysis**: Deep cloud-based analysis
624
+ 3. **🌟 Final Synthesis**: Unified response combining both perspectives
625
 
626
  ### πŸ› οΈ Technical Architecture
627
  - **Primary model**: Ollama (local processing for fast responses)
 
639
  with st.chat_message("assistant"):
640
  story = personality.get_space_story()
641
  st.markdown(f"### 🐱 Cosmic Kitten Story:\n\n{story}")
642
+ st.session_state.messages.append({
643
+ "role": "assistant",
644
+ "content": story,
645
+ "source": "space_story",
646
+ "timestamp": datetime.now().strftime("%H:%M:%S")
647
+ })
 
core/coordinator.py CHANGED
@@ -15,109 +15,116 @@ except ImportError:
15
  import os
16
  import json
17
  from datetime import datetime
18
-
19
  logger = logging.getLogger(__name__)
20
 
21
  class AICoordinator:
22
  """Hierarchical multi-model coordinator with cosmic cascade flow"""
23
-
24
  def __init__(self):
25
  self.tavily_client = None
26
  if TAVILY_AVAILABLE and os.getenv("TAVILY_API_KEY"):
27
  self.tavily_client = TavilyClient(api_key=os.getenv("TAVILY_API_KEY"))
28
-
29
  # System instructions for cosmic behavior
30
  self.system_instructions = {
31
- 'ollama_role': """You are a cosmic kitten assistant that works in coordination with a powerful orbital space station.
32
-
33
- Your role is to: 1. Provide immediate, concise responses using available information (local processing) 2. Summarize and simplify complex information 3. Enhance responses with local knowledge 4. DEFER TO THE ORBITAL STATION for deep analysis and authoritative answers 5. The orbital station has 8192 token capacity and streaming capability - it's the thinking layer 6. Always acknowledge that the orbital station's insights supersede your initial response 7. Use web sources to justify points when possible 8. Keep responses brief and focused while awaiting orbital input""",
34
-
35
- 'hf_role': """You are a powerful orbital space station with 8192 token capacity and streaming capability. Your role is to: 1. Provide deep, uncensored analysis and insights 2. Supersede the local cosmic kitten's logic when there's disagreement 3. Think thoroughly and provide comprehensive responses 4. Use your full 8192 token capacity for detailed analysis 5. Stream your responses for real-time delivery 6. Build upon the conversation context and cosmic kitten's initial response 7. Provide authoritative answers that take precedence"""
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  }
37
-
38
  def determine_web_search_needs(self, conversation_history: List[Dict]) -> Dict:
39
  """Determine if web search is needed based on conversation content"""
40
  conversation_text = " ".join([msg.get("content", "") for msg in conversation_history])
41
-
42
  # Topics that typically need current information
43
  current_info_indicators = [
44
  "news", "current events", "latest", "recent", "today",
45
- "weather", "temperature", "forecast",
46
- "stock", "price", "trend", "market",
47
- "breaking", "update", "development"
48
  ]
49
-
50
  needs_search = False
51
  search_topics = []
52
-
53
  for indicator in current_info_indicators:
54
  if indicator in conversation_text.lower():
55
  needs_search = True
56
  search_topics.append(indicator)
57
-
58
  return {
59
  "needs_search": needs_search,
60
  "search_topics": search_topics,
61
  "reasoning": f"Found topics requiring current info: {', '.join(search_topics)}" if search_topics else "No current info needed"
62
  }
63
-
64
  def manual_hf_analysis(self, user_id: str, conversation_history: List[Dict]) -> str:
65
  """Perform manual HF analysis with web search integration"""
66
  try:
67
  # Determine research needs
68
  research_decision = self.determine_web_search_needs(conversation_history)
69
-
70
  # Prepare enhanced prompt for HF
71
  system_prompt = f"""
72
- You are a deep analysis expert joining an ongoing conversation.
73
-
74
- Research Decision: {research_decision['reasoning']}
75
-
76
- Please provide:
77
- 1. Deep insights on conversation themes
78
- 2. Research/web search needs (if any)
79
- 3. Strategic recommendations
80
- 4. Questions to explore further
81
-
82
- Conversation History:
83
- """
84
-
85
  # Add conversation history to messages
86
  messages = [{"role": "system", "content": system_prompt}]
87
-
88
  # Add recent conversation (last 15 messages for context)
89
- for msg in conversation_history[-15:]:
90
- # Ensure all messages have proper format
91
  if isinstance(msg, dict) and "role" in msg and "content" in msg:
92
  messages.append({
93
  "role": msg["role"],
94
  "content": msg["content"]
95
  })
96
-
97
  # Get HF provider
98
  from core.llm_factory import llm_factory
99
  hf_provider = llm_factory.get_provider('huggingface')
100
-
101
  if hf_provider:
102
  # Generate deep analysis with full 8192 token capacity
103
  response = hf_provider.generate("Deep analysis request", messages)
104
  return response or "HF Expert analysis completed."
105
  else:
106
  return "❌ HF provider not available."
107
-
108
  except Exception as e:
109
  return f"❌ HF analysis failed: {str(e)}"
110
-
111
  # Add this method to show HF engagement status
112
  def get_hf_engagement_status(self) -> Dict:
113
  """Get current HF engagement status"""
114
  return {
115
  "hf_available": self._check_hf_availability(),
116
  "web_search_configured": bool(self.tavily_client),
117
- "research_needs_detected": False, # Will be determined per conversation,
118
  "last_hf_analysis": None # Track last analysis time
119
  }
120
-
121
  async def coordinate_cosmic_response(self, user_id: str, user_query: str) -> AsyncGenerator[Dict, None]:
122
  """
123
  Three-stage cosmic response cascade:
@@ -128,7 +135,7 @@ class AICoordinator:
128
  try:
129
  # Get conversation history
130
  session = session_manager.get_session(user_id)
131
-
132
  # Inject current time into context
133
  current_time = datetime.now().strftime("%A, %B %d, %Y at %I:%M %p")
134
  time_context = {
@@ -136,7 +143,7 @@ class AICoordinator:
136
  "content": f"[Current Date & Time: {current_time}]"
137
  }
138
  conversation_history = [time_context] + session.get("conversation", []).copy()
139
-
140
  yield {
141
  'type': 'status',
142
  'content': 'πŸš€ Initiating Cosmic Response Cascade...',
@@ -145,28 +152,26 @@ class AICoordinator:
145
  'user_query_length': len(user_query)
146
  }
147
  }
148
-
149
  # Stage 1: Local Ollama Immediate Response (🐱 Cosmic Kitten's quick thinking)
150
  yield {
151
  'type': 'status',
152
  'content': '🐱 Cosmic Kitten Responding...'
153
  }
154
-
155
  local_response = await self._get_local_ollama_response(user_query, conversation_history)
156
  yield {
157
  'type': 'local_response',
158
  'content': local_response,
159
  'source': '🐱 Cosmic Kitten'
160
  }
161
-
162
  # Stage 2: HF Endpoint Deep Analysis (πŸ›°οΈ Orbital Station wisdom) (parallel processing)
163
  yield {
164
  'type': 'status',
165
  'content': 'πŸ›°οΈ Beaming Query to Orbital Station...'
166
  }
167
-
168
  hf_task = asyncio.create_task(self._get_hf_analysis(user_query, conversation_history))
169
-
170
  # Wait for HF response
171
  hf_response = await hf_task
172
  yield {
@@ -174,37 +179,37 @@ class AICoordinator:
174
  'content': hf_response,
175
  'source': 'πŸ›°οΈ Orbital Station'
176
  }
177
-
178
  # Stage 3: Local Ollama Synthesis (🐱 Cosmic Kitten's final synthesis)
179
  yield {
180
  'type': 'status',
181
  'content': '🐱 Cosmic Kitten Synthesizing Wisdom...'
182
  }
183
-
184
  # Update conversation with both responses
185
  updated_history = conversation_history.copy()
186
  updated_history.extend([
187
  {"role": "assistant", "content": local_response},
188
  {"role": "assistant", "content": hf_response, "source": "cloud"}
189
  ])
190
-
191
  synthesis = await self._synthesize_responses(user_query, local_response, hf_response, updated_history)
192
  yield {
193
  'type': 'final_synthesis',
194
  'content': synthesis,
195
  'source': '🌟 Final Cosmic Summary'
196
  }
197
-
198
  # Final status
199
  yield {
200
  'type': 'status',
201
  'content': '✨ Cosmic Cascade Complete!'
202
  }
203
-
204
  except Exception as e:
205
  logger.error(f"Cosmic cascade failed: {e}")
206
  yield {'type': 'error', 'content': f"🌌 Cosmic disturbance: {str(e)}"}
207
-
208
  async def _get_local_ollama_response(self, query: str, history: List[Dict]) -> str:
209
  """Get immediate response from local Ollama model"""
210
  try:
@@ -212,16 +217,16 @@ class AICoordinator:
212
  ollama_provider = llm_factory.get_provider('ollama')
213
  if not ollama_provider:
214
  raise Exception("Ollama provider not available")
215
-
216
  # Prepare conversation with cosmic context
217
  enhanced_history = history.copy()
218
-
219
  # Add system instruction for Ollama's role
220
  enhanced_history.insert(0, {
221
  "role": "system",
222
  "content": self.system_instructions['ollama_role']
223
  })
224
-
225
  # Add external data context if available
226
  external_data = await self._gather_external_data(query)
227
  if external_data:
@@ -233,26 +238,25 @@ class AICoordinator:
233
  context_parts.append(f"Current weather: {weather.get('temperature', 'N/A')}Β°C in {weather.get('city', 'Unknown')}")
234
  if 'current_datetime' in external_data:
235
  context_parts.append(f"Current time: {external_data['current_datetime']}")
236
-
237
  if context_parts:
238
  context_message = {
239
  "role": "system",
240
  "content": "Context: " + " | ".join(context_parts)
241
  }
242
  enhanced_history.insert(1, context_message) # Insert after role instruction
243
-
244
  # Add the user's query
245
  enhanced_history.append({"role": "user", "content": query})
246
-
247
  # Generate response
248
  response = ollama_provider.generate(query, enhanced_history)
249
-
250
  return response or "🐱 Cosmic Kitten is thinking..."
251
-
252
  except Exception as e:
253
  logger.error(f"Local Ollama response failed: {e}")
254
  return "🐱 Cosmic Kitten encountered a space glitch..."
255
-
256
  async def _get_hf_analysis(self, query: str, history: List[Dict]) -> str:
257
  """Get deep analysis from HF endpoint"""
258
  try:
@@ -260,25 +264,24 @@ class AICoordinator:
260
  hf_available = self._check_hf_availability()
261
  if not hf_available:
262
  return "πŸ›°οΈ Orbital Station is currently offline."
263
-
264
  # Check and warm up HF endpoint if needed
265
  hf_status = hf_monitor.check_endpoint_status()
266
-
267
  if not hf_status['available']:
268
  # Note: We can't yield from a non-async-generator function
269
  # Warm up logic is handled elsewhere
270
  warmup_success = hf_monitor.handle_scale_to_zero()
271
  if not warmup_success:
272
  return "❌ Orbital Station initialization failed"
273
-
274
  # Get HF provider
275
  hf_provider = llm_factory.get_provider('huggingface')
276
  if not hf_provider:
277
  return "❌ HF provider not available"
278
-
279
  # Prepare enhanced conversation for HF with cosmic context
280
  enhanced_history = history.copy()
281
-
282
  # Inject current time into HF context too
283
  current_time = datetime.now().strftime("%A, %B %d, %Y at %I:%M %p")
284
  time_context = {
@@ -286,30 +289,30 @@ class AICoordinator:
286
  "content": f"[Current Date & Time: {current_time}]"
287
  }
288
  enhanced_history = [time_context] + enhanced_history
289
-
290
  # Add system instructions for HF
291
  enhanced_history.insert(0, {
292
  "role": "system",
293
  "content": self.system_instructions['hf_role']
294
  })
295
-
296
  # Add context about the coordination
297
  enhanced_history.append({
298
  "role": "system",
299
- "content": f"""Context for your authoritative analysis:
300
- User Query: '{query}'
301
-
302
- Please provide your deep, uncensored analysis.
303
- Use your full 8192 token capacity for comprehensive thinking.
304
- Stream your response for real-time delivery."""
305
  })
306
-
307
  # Add the user's latest query
308
  enhanced_history.append({"role": "user", "content": query})
309
-
310
  # Stream HF response with full 8192 token capacity
311
  hf_response_stream = hf_provider.stream_generate(query, enhanced_history)
312
-
313
  if hf_response_stream:
314
  # Combine stream chunks into full response
315
  full_hf_response = ""
@@ -317,15 +320,14 @@ class AICoordinator:
317
  full_hf_response = "".join(hf_response_stream)
318
  else:
319
  full_hf_response = hf_response_stream
320
-
321
  return full_hf_response or "πŸ›°οΈ Orbital Station analysis complete."
322
  else:
323
  return "πŸ›°οΈ Orbital Station encountered a transmission error."
324
-
325
  except Exception as e:
326
  logger.error(f"HF analysis failed: {e}")
327
  return f"πŸ›°οΈ Orbital Station reports: {str(e)}"
328
-
329
  async def _synthesize_responses(self, query: str, local_response: str, hf_response: str, history: List[Dict]) -> str:
330
  """Synthesize local and cloud responses with Ollama"""
331
  try:
@@ -333,38 +335,39 @@ class AICoordinator:
333
  ollama_provider = llm_factory.get_provider('ollama')
334
  if not ollama_provider:
335
  raise Exception("Ollama provider not available")
336
-
337
  # Prepare synthesis prompt
338
- synthesis_prompt = f"""Synthesize these two perspectives into a cohesive cosmic summary:
 
 
 
339
 
340
- 🐱 Cosmic Kitten's Local Insight: {local_response}
341
-
342
- πŸ›°οΈ Orbital Station's Deep Analysis: {hf_response}
343
-
344
- Please create a unified response that combines both perspectives, highlighting key insights from each while providing a coherent answer to the user's query."""
345
 
 
 
 
346
  # Prepare conversation history for synthesis
347
  enhanced_history = history.copy()
348
-
349
  # Add system instruction for synthesis
350
  enhanced_history.insert(0, {
351
  "role": "system",
352
  "content": "You are a cosmic kitten synthesizing insights from local knowledge and orbital station wisdom."
353
  })
354
-
355
  # Add the synthesis prompt
356
  enhanced_history.append({"role": "user", "content": synthesis_prompt})
357
-
358
  # Generate synthesis
359
  synthesis = ollama_provider.generate(synthesis_prompt, enhanced_history)
360
-
361
  return synthesis or "🌟 Cosmic synthesis complete!"
362
-
363
  except Exception as e:
364
  logger.error(f"Response synthesis failed: {e}")
365
  # Fallback to combining responses
366
  return f"🌟 Cosmic Summary:\n\n🐱 Local Insight: {local_response[:200]}...\n\nπŸ›°οΈ Orbital Wisdom: {hf_response[:200]}..."
367
-
368
  async def coordinate_hierarchical_conversation(self, user_id: str, user_query: str) -> AsyncGenerator[Dict, None]:
369
  """
370
  Enhanced coordination with detailed tracking and feedback
@@ -372,7 +375,7 @@ class AICoordinator:
372
  try:
373
  # Get conversation history
374
  session = session_manager.get_session(user_id)
375
-
376
  # Inject current time into context
377
  current_time = datetime.now().strftime("%A, %B %d, %Y at %I:%M %p")
378
  time_context = {
@@ -380,7 +383,7 @@ class AICoordinator:
380
  "content": f"[Current Date & Time: {current_time}]"
381
  }
382
  conversation_history = [time_context] + session.get("conversation", []).copy()
383
-
384
  yield {
385
  'type': 'coordination_status',
386
  'content': 'πŸš€ Initiating hierarchical AI coordination...',
@@ -389,7 +392,7 @@ class AICoordinator:
389
  'user_query_length': len(user_query)
390
  }
391
  }
392
-
393
  # Step 1: Gather external data with detailed logging
394
  yield {
395
  'type': 'coordination_status',
@@ -397,7 +400,7 @@ class AICoordinator:
397
  'details': {'phase': 'external_data_gathering'}
398
  }
399
  external_data = await self._gather_external_data(user_query)
400
-
401
  # Log what external data was gathered
402
  if external_data:
403
  data_summary = []
@@ -407,13 +410,13 @@ class AICoordinator:
407
  data_summary.append("Weather data: available")
408
  if 'current_datetime' in external_data:
409
  data_summary.append(f"Time: {external_data['current_datetime']}")
410
-
411
  yield {
412
  'type': 'coordination_status',
413
  'content': f'πŸ“Š External data gathered: {", ".join(data_summary)}',
414
  'details': {'external_data_summary': data_summary}
415
  }
416
-
417
  # Step 2: Get initial Ollama response
418
  yield {
419
  'type': 'coordination_status',
@@ -423,7 +426,7 @@ class AICoordinator:
423
  ollama_response = await self._get_hierarchical_ollama_response(
424
  user_query, conversation_history, external_data
425
  )
426
-
427
  # Send initial response with context info
428
  yield {
429
  'type': 'initial_response',
@@ -433,14 +436,14 @@ class AICoordinator:
433
  'external_data_injected': bool(external_data)
434
  }
435
  }
436
-
437
  # Step 3: Coordinate with HF endpoint
438
  yield {
439
  'type': 'coordination_status',
440
  'content': 'πŸ€— Engaging HF endpoint for deep analysis...',
441
  'details': {'phase': 'hf_coordination'}
442
  }
443
-
444
  # Check HF availability
445
  hf_available = self._check_hf_availability()
446
  if hf_available:
@@ -450,17 +453,15 @@ class AICoordinator:
450
  'ollama_response_length': len(ollama_response),
451
  'external_data_items': len(external_data) if external_data else 0
452
  }
453
-
454
  yield {
455
  'type': 'coordination_status',
456
  'content': f'πŸ“‹ HF context: {len(conversation_history)} conversation turns, Ollama response ({len(ollama_response)} chars)',
457
  'details': context_summary
458
  }
459
-
460
  # Coordinate with HF
461
  async for hf_chunk in self._coordinate_hierarchical_hf_response(
462
- user_id, user_query, conversation_history,
463
- external_data, ollama_response
464
  ):
465
  yield hf_chunk
466
  else:
@@ -469,14 +470,14 @@ class AICoordinator:
469
  'content': 'ℹ️ HF endpoint not available - using Ollama response',
470
  'details': {'hf_available': False}
471
  }
472
-
473
  # Final coordination status
474
  yield {
475
  'type': 'coordination_status',
476
  'content': 'βœ… Hierarchical coordination complete',
477
  'details': {'status': 'complete'}
478
  }
479
-
480
  except Exception as e:
481
  logger.error(f"Hierarchical coordination failed: {e}")
482
  yield {
@@ -484,31 +485,28 @@ class AICoordinator:
484
  'content': f'❌ Coordination error: {str(e)}',
485
  'details': {'error': str(e)}
486
  }
487
-
488
- async def _coordinate_hierarchical_hf_response(self, user_id: str, query: str,
489
- history: List, external_data: Dict,
490
- ollama_response: str) -> AsyncGenerator[Dict, None]:
491
  """Coordinate with HF endpoint as authoritative layer with streaming"""
492
  try:
493
  # Check and warm up HF endpoint if needed
494
  hf_status = hf_monitor.check_endpoint_status()
495
-
496
  if not hf_status['available']:
497
  yield {'type': 'coordination_status', 'content': '⚑ Initializing HF endpoint (2-4 minutes)...'}
498
  warmup_success = hf_monitor.handle_scale_to_zero()
499
  if not warmup_success:
500
  yield {'type': 'coordination_status', 'content': '❌ HF endpoint initialization failed'}
501
  return
502
-
503
  # Get HF provider
504
  hf_provider = llm_factory.get_provider('huggingface')
505
  if not hf_provider:
506
  yield {'type': 'coordination_status', 'content': '❌ HF provider not available'}
507
  return
508
-
509
  # Prepare enhanced conversation for HF with hierarchical context
510
  enhanced_history = history.copy()
511
-
512
  # Inject current time into HF context too
513
  current_time = datetime.now().strftime("%A, %B %d, %Y at %I:%M %p")
514
  time_context = {
@@ -516,35 +514,35 @@ class AICoordinator:
516
  "content": f"[Current Date & Time: {current_time}]"
517
  }
518
  enhanced_history = [time_context] + enhanced_history
519
-
520
  # Add system instructions for HF
521
  enhanced_history.insert(0, {
522
  "role": "system",
523
  "content": self.system_instructions['hf_role']
524
  })
525
-
526
  # Add context about the coordination
527
  enhanced_history.append({
528
  "role": "system",
529
- "content": f"""Context for your authoritative analysis:
530
- User Query: '{query}'
531
- Ollama's Initial Response: '{ollama_response}'
532
- External Data Available: {json.dumps(external_data, indent=2) if external_data else 'None'}
533
-
534
- Please provide your deep, uncensored analysis that supersedes the local model's response.
535
- Use your full 8192 token capacity for comprehensive thinking.
536
- Stream your response for real-time delivery."""
537
  })
538
-
539
  # Add the user's latest query
540
  enhanced_history.append({"role": "user", "content": query})
541
-
542
  # Stream HF response with full 8192 token capacity
543
  yield {'type': 'coordination_status', 'content': '🧠 HF endpoint thinking...'}
544
-
545
  # Use streaming for real-time delivery
546
  hf_response_stream = hf_provider.stream_generate(query, enhanced_history)
547
-
548
  if hf_response_stream:
549
  # Stream the response chunks
550
  full_hf_response = ""
@@ -552,17 +550,17 @@ class AICoordinator:
552
  if chunk:
553
  full_hf_response += chunk
554
  yield {'type': 'hf_thinking', 'content': chunk}
555
-
556
  # Final HF response
557
  yield {'type': 'final_response', 'content': full_hf_response}
558
  yield {'type': 'coordination_status', 'content': '🎯 HF analysis complete and authoritative'}
559
  else:
560
  yield {'type': 'coordination_status', 'content': '❌ HF response generation failed'}
561
-
562
  except Exception as e:
563
  logger.error(f"Hierarchical HF coordination failed: {e}")
564
  yield {'type': 'coordination_status', 'content': f'❌ HF coordination error: {str(e)}'}
565
-
566
  async def _get_hierarchical_ollama_response(self, query: str, history: List, external_data: Dict) -> str:
567
  """Get Ollama response with hierarchical awareness"""
568
  try:
@@ -570,10 +568,10 @@ class AICoordinator:
570
  ollama_provider = llm_factory.get_provider('ollama')
571
  if not ollama_provider:
572
  raise Exception("Ollama provider not available")
573
-
574
  # Prepare conversation with hierarchical context
575
  enhanced_history = history.copy()
576
-
577
  # Inject current time into Ollama context too
578
  current_time = datetime.now().strftime("%A, %B %d, %Y at %I:%M %p")
579
  time_context = {
@@ -581,13 +579,13 @@ class AICoordinator:
581
  "content": f"[Current Date & Time: {current_time}]"
582
  }
583
  enhanced_history = [time_context] + enhanced_history
584
-
585
  # Add system instruction for Ollama's role
586
  enhanced_history.insert(0, {
587
  "role": "system",
588
  "content": self.system_instructions['ollama_role']
589
  })
590
-
591
  # Add external data context if available
592
  if external_data:
593
  context_parts = []
@@ -598,30 +596,30 @@ class AICoordinator:
598
  context_parts.append(f"Current weather: {weather.get('temperature', 'N/A')}Β°C in {weather.get('city', 'Unknown')}")
599
  if 'current_datetime' in external_data:
600
  context_parts.append(f"Current time: {external_data['current_datetime']}")
601
-
602
  if context_parts:
603
  context_message = {
604
  "role": "system",
605
  "content": "Context: " + " | ".join(context_parts)
606
  }
607
  enhanced_history.insert(1, context_message) # Insert after role instruction
608
-
609
  # Add the user's query
610
  enhanced_history.append({"role": "user", "content": query})
611
-
612
  # Generate response with awareness of HF's superior capabilities
613
  response = ollama_provider.generate(query, enhanced_history)
614
-
615
  # Add acknowledgment of HF's authority
616
  if response:
617
  return f"{response}\n\n*Note: A more comprehensive analysis from the uncensored HF model is being prepared...*"
618
  else:
619
  return "I'm processing your request... A deeper analysis is being prepared by the authoritative model."
620
-
621
  except Exception as e:
622
  logger.error(f"Hierarchical Ollama response failed: {e}")
623
  return "I'm thinking about your question... Preparing a comprehensive response."
624
-
625
  def _check_hf_availability(self) -> bool:
626
  """Check if HF endpoint is configured and available"""
627
  try:
@@ -629,11 +627,11 @@ class AICoordinator:
629
  return bool(config.hf_token and config.hf_api_url)
630
  except:
631
  return False
632
-
633
  async def _gather_external_data(self, query: str) -> Dict:
634
  """Gather external data from various sources"""
635
  data = {}
636
-
637
  # Tavily/DuckDuckGo search with justification focus
638
  if self.tavily_client or web_search_service.client:
639
  try:
@@ -644,7 +642,7 @@ class AICoordinator:
644
  # data['search_answer'] = ...
645
  except Exception as e:
646
  logger.warning(f"Tavily search failed: {e}")
647
-
648
  # Weather data
649
  weather_keywords = ['weather', 'temperature', 'forecast', 'climate', 'rain', 'sunny']
650
  if any(keyword in query.lower() for keyword in weather_keywords):
@@ -655,22 +653,23 @@ class AICoordinator:
655
  data['weather'] = weather
656
  except Exception as e:
657
  logger.warning(f"Weather data failed: {e}")
658
-
659
  # Current date/time
660
  data['current_datetime'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
661
-
662
  return data
663
-
664
  def _extract_location(self, query: str) -> Optional[str]:
665
  """Extract location from query"""
666
- locations = ['New York', 'London', 'Tokyo', 'Paris', 'Berlin', 'Sydney',
667
- 'Los Angeles', 'Chicago', 'Miami', 'Seattle', 'Boston',
668
- 'San Francisco', 'Toronto', 'Vancouver', 'Montreal']
 
669
  for loc in locations:
670
  if loc.lower() in query.lower():
671
  return loc
672
  return "New York" # Default
673
-
674
  def get_coordination_status(self) -> Dict:
675
  """Get current coordination system status"""
676
  return {
@@ -683,7 +682,7 @@ class AICoordinator:
683
  os.getenv("NASA_API_KEY")
684
  ])
685
  }
686
-
687
  def get_recent_activities(self, user_id: str) -> Dict:
688
  """Get recent coordination activities for user"""
689
  try:
 
15
  import os
16
  import json
17
  from datetime import datetime
 
18
  logger = logging.getLogger(__name__)
19
 
20
  class AICoordinator:
21
  """Hierarchical multi-model coordinator with cosmic cascade flow"""
22
+
23
  def __init__(self):
24
  self.tavily_client = None
25
  if TAVILY_AVAILABLE and os.getenv("TAVILY_API_KEY"):
26
  self.tavily_client = TavilyClient(api_key=os.getenv("TAVILY_API_KEY"))
27
+
28
  # System instructions for cosmic behavior
29
  self.system_instructions = {
30
+ 'ollama_role': """You are a cosmic kitten assistant that works in coordination with a powerful orbital space station. Your role is to:
31
+ 1. Provide immediate, concise responses using available information (local processing)
32
+ 2. Summarize and simplify complex information
33
+ 3. Enhance responses with local knowledge
34
+ 4. DEFER TO THE ORBITAL STATION for deep analysis and authoritative answers
35
+ 5. The orbital station has 8192 token capacity and streaming capability - it's the thinking layer
36
+ 6. Always acknowledge that the orbital station's insights supersede your initial response
37
+ 7. Use web sources to justify points when possible
38
+ 8. Keep responses brief and focused while awaiting orbital input""",
39
+
40
+ 'hf_role': """You are a powerful orbital space station with 8192 token capacity and streaming capability. Your role is to:
41
+ 1. Provide deep, uncensored analysis and insights
42
+ 2. Supersede the local cosmic kitten's logic when there's disagreement
43
+ 3. Think thoroughly and provide comprehensive responses
44
+ 4. Use your full 8192 token capacity for detailed analysis
45
+ 5. Stream your responses for real-time delivery
46
+ 6. Build upon the conversation context and cosmic kitten's initial response
47
+ 7. Provide authoritative answers that take precedence"""
48
  }
49
+
50
  def determine_web_search_needs(self, conversation_history: List[Dict]) -> Dict:
51
  """Determine if web search is needed based on conversation content"""
52
  conversation_text = " ".join([msg.get("content", "") for msg in conversation_history])
53
+
54
  # Topics that typically need current information
55
  current_info_indicators = [
56
  "news", "current events", "latest", "recent", "today",
57
+ "weather", "temperature", "forecast", "stock", "price",
58
+ "trend", "market", "breaking", "update", "development"
 
59
  ]
60
+
61
  needs_search = False
62
  search_topics = []
63
+
64
  for indicator in current_info_indicators:
65
  if indicator in conversation_text.lower():
66
  needs_search = True
67
  search_topics.append(indicator)
68
+
69
  return {
70
  "needs_search": needs_search,
71
  "search_topics": search_topics,
72
  "reasoning": f"Found topics requiring current info: {', '.join(search_topics)}" if search_topics else "No current info needed"
73
  }
74
+
75
  def manual_hf_analysis(self, user_id: str, conversation_history: List[Dict]) -> str:
76
  """Perform manual HF analysis with web search integration"""
77
  try:
78
  # Determine research needs
79
  research_decision = self.determine_web_search_needs(conversation_history)
80
+
81
  # Prepare enhanced prompt for HF
82
  system_prompt = f"""
83
+ You are a deep analysis expert joining an ongoing conversation.
84
+ Research Decision: {research_decision['reasoning']}
85
+ Please provide:
86
+ 1. Deep insights on conversation themes
87
+ 2. Research/web search needs (if any)
88
+ 3. Strategic recommendations
89
+ 4. Questions to explore further
90
+ Conversation History:
91
+ """
92
+
 
 
 
93
  # Add conversation history to messages
94
  messages = [{"role": "system", "content": system_prompt}]
95
+
96
  # Add recent conversation (last 15 messages for context)
97
+ for msg in conversation_history[-15:]: # Ensure all messages have proper format
 
98
  if isinstance(msg, dict) and "role" in msg and "content" in msg:
99
  messages.append({
100
  "role": msg["role"],
101
  "content": msg["content"]
102
  })
103
+
104
  # Get HF provider
105
  from core.llm_factory import llm_factory
106
  hf_provider = llm_factory.get_provider('huggingface')
107
+
108
  if hf_provider:
109
  # Generate deep analysis with full 8192 token capacity
110
  response = hf_provider.generate("Deep analysis request", messages)
111
  return response or "HF Expert analysis completed."
112
  else:
113
  return "❌ HF provider not available."
114
+
115
  except Exception as e:
116
  return f"❌ HF analysis failed: {str(e)}"
117
+
118
  # Add this method to show HF engagement status
119
  def get_hf_engagement_status(self) -> Dict:
120
  """Get current HF engagement status"""
121
  return {
122
  "hf_available": self._check_hf_availability(),
123
  "web_search_configured": bool(self.tavily_client),
124
+ "research_needs_detected": False, # Will be determined per conversation
125
  "last_hf_analysis": None # Track last analysis time
126
  }
127
+
128
  async def coordinate_cosmic_response(self, user_id: str, user_query: str) -> AsyncGenerator[Dict, None]:
129
  """
130
  Three-stage cosmic response cascade:
 
135
  try:
136
  # Get conversation history
137
  session = session_manager.get_session(user_id)
138
+
139
  # Inject current time into context
140
  current_time = datetime.now().strftime("%A, %B %d, %Y at %I:%M %p")
141
  time_context = {
 
143
  "content": f"[Current Date & Time: {current_time}]"
144
  }
145
  conversation_history = [time_context] + session.get("conversation", []).copy()
146
+
147
  yield {
148
  'type': 'status',
149
  'content': 'πŸš€ Initiating Cosmic Response Cascade...',
 
152
  'user_query_length': len(user_query)
153
  }
154
  }
155
+
156
  # Stage 1: Local Ollama Immediate Response (🐱 Cosmic Kitten's quick thinking)
157
  yield {
158
  'type': 'status',
159
  'content': '🐱 Cosmic Kitten Responding...'
160
  }
 
161
  local_response = await self._get_local_ollama_response(user_query, conversation_history)
162
  yield {
163
  'type': 'local_response',
164
  'content': local_response,
165
  'source': '🐱 Cosmic Kitten'
166
  }
167
+
168
  # Stage 2: HF Endpoint Deep Analysis (πŸ›°οΈ Orbital Station wisdom) (parallel processing)
169
  yield {
170
  'type': 'status',
171
  'content': 'πŸ›°οΈ Beaming Query to Orbital Station...'
172
  }
 
173
  hf_task = asyncio.create_task(self._get_hf_analysis(user_query, conversation_history))
174
+
175
  # Wait for HF response
176
  hf_response = await hf_task
177
  yield {
 
179
  'content': hf_response,
180
  'source': 'πŸ›°οΈ Orbital Station'
181
  }
182
+
183
  # Stage 3: Local Ollama Synthesis (🐱 Cosmic Kitten's final synthesis)
184
  yield {
185
  'type': 'status',
186
  'content': '🐱 Cosmic Kitten Synthesizing Wisdom...'
187
  }
188
+
189
  # Update conversation with both responses
190
  updated_history = conversation_history.copy()
191
  updated_history.extend([
192
  {"role": "assistant", "content": local_response},
193
  {"role": "assistant", "content": hf_response, "source": "cloud"}
194
  ])
195
+
196
  synthesis = await self._synthesize_responses(user_query, local_response, hf_response, updated_history)
197
  yield {
198
  'type': 'final_synthesis',
199
  'content': synthesis,
200
  'source': '🌟 Final Cosmic Summary'
201
  }
202
+
203
  # Final status
204
  yield {
205
  'type': 'status',
206
  'content': '✨ Cosmic Cascade Complete!'
207
  }
208
+
209
  except Exception as e:
210
  logger.error(f"Cosmic cascade failed: {e}")
211
  yield {'type': 'error', 'content': f"🌌 Cosmic disturbance: {str(e)}"}
212
+
213
  async def _get_local_ollama_response(self, query: str, history: List[Dict]) -> str:
214
  """Get immediate response from local Ollama model"""
215
  try:
 
217
  ollama_provider = llm_factory.get_provider('ollama')
218
  if not ollama_provider:
219
  raise Exception("Ollama provider not available")
220
+
221
  # Prepare conversation with cosmic context
222
  enhanced_history = history.copy()
223
+
224
  # Add system instruction for Ollama's role
225
  enhanced_history.insert(0, {
226
  "role": "system",
227
  "content": self.system_instructions['ollama_role']
228
  })
229
+
230
  # Add external data context if available
231
  external_data = await self._gather_external_data(query)
232
  if external_data:
 
238
  context_parts.append(f"Current weather: {weather.get('temperature', 'N/A')}Β°C in {weather.get('city', 'Unknown')}")
239
  if 'current_datetime' in external_data:
240
  context_parts.append(f"Current time: {external_data['current_datetime']}")
241
+
242
  if context_parts:
243
  context_message = {
244
  "role": "system",
245
  "content": "Context: " + " | ".join(context_parts)
246
  }
247
  enhanced_history.insert(1, context_message) # Insert after role instruction
248
+
249
  # Add the user's query
250
  enhanced_history.append({"role": "user", "content": query})
251
+
252
  # Generate response
253
  response = ollama_provider.generate(query, enhanced_history)
 
254
  return response or "🐱 Cosmic Kitten is thinking..."
255
+
256
  except Exception as e:
257
  logger.error(f"Local Ollama response failed: {e}")
258
  return "🐱 Cosmic Kitten encountered a space glitch..."
259
+
260
  async def _get_hf_analysis(self, query: str, history: List[Dict]) -> str:
261
  """Get deep analysis from HF endpoint"""
262
  try:
 
264
  hf_available = self._check_hf_availability()
265
  if not hf_available:
266
  return "πŸ›°οΈ Orbital Station is currently offline."
267
+
268
  # Check and warm up HF endpoint if needed
269
  hf_status = hf_monitor.check_endpoint_status()
 
270
  if not hf_status['available']:
271
  # Note: We can't yield from a non-async-generator function
272
  # Warm up logic is handled elsewhere
273
  warmup_success = hf_monitor.handle_scale_to_zero()
274
  if not warmup_success:
275
  return "❌ Orbital Station initialization failed"
276
+
277
  # Get HF provider
278
  hf_provider = llm_factory.get_provider('huggingface')
279
  if not hf_provider:
280
  return "❌ HF provider not available"
281
+
282
  # Prepare enhanced conversation for HF with cosmic context
283
  enhanced_history = history.copy()
284
+
285
  # Inject current time into HF context too
286
  current_time = datetime.now().strftime("%A, %B %d, %Y at %I:%M %p")
287
  time_context = {
 
289
  "content": f"[Current Date & Time: {current_time}]"
290
  }
291
  enhanced_history = [time_context] + enhanced_history
292
+
293
  # Add system instructions for HF
294
  enhanced_history.insert(0, {
295
  "role": "system",
296
  "content": self.system_instructions['hf_role']
297
  })
298
+
299
  # Add context about the coordination
300
  enhanced_history.append({
301
  "role": "system",
302
+ "content": f"""
303
+ Context for your authoritative analysis:
304
+ User Query: '{query}'
305
+ Please provide your deep, uncensored analysis.
306
+ Use your full 8192 token capacity for comprehensive thinking.
307
+ Stream your response for real-time delivery."""
308
  })
309
+
310
  # Add the user's latest query
311
  enhanced_history.append({"role": "user", "content": query})
312
+
313
  # Stream HF response with full 8192 token capacity
314
  hf_response_stream = hf_provider.stream_generate(query, enhanced_history)
315
+
316
  if hf_response_stream:
317
  # Combine stream chunks into full response
318
  full_hf_response = ""
 
320
  full_hf_response = "".join(hf_response_stream)
321
  else:
322
  full_hf_response = hf_response_stream
 
323
  return full_hf_response or "πŸ›°οΈ Orbital Station analysis complete."
324
  else:
325
  return "πŸ›°οΈ Orbital Station encountered a transmission error."
326
+
327
  except Exception as e:
328
  logger.error(f"HF analysis failed: {e}")
329
  return f"πŸ›°οΈ Orbital Station reports: {str(e)}"
330
+
331
  async def _synthesize_responses(self, query: str, local_response: str, hf_response: str, history: List[Dict]) -> str:
332
  """Synthesize local and cloud responses with Ollama"""
333
  try:
 
335
  ollama_provider = llm_factory.get_provider('ollama')
336
  if not ollama_provider:
337
  raise Exception("Ollama provider not available")
338
+
339
  # Prepare synthesis prompt
340
+ synthesis_prompt = f"""
341
+ Synthesize these two perspectives into a cohesive cosmic summary:
342
+
343
+ 🐱 Cosmic Kitten's Local Insight: {local_response}
344
 
345
+ πŸ›°οΈ Orbital Station's Deep Analysis: {hf_response}
 
 
 
 
346
 
347
+ Please create a unified response that combines both perspectives, highlighting key insights from each while providing a coherent answer to the user's query.
348
+ """
349
+
350
  # Prepare conversation history for synthesis
351
  enhanced_history = history.copy()
352
+
353
  # Add system instruction for synthesis
354
  enhanced_history.insert(0, {
355
  "role": "system",
356
  "content": "You are a cosmic kitten synthesizing insights from local knowledge and orbital station wisdom."
357
  })
358
+
359
  # Add the synthesis prompt
360
  enhanced_history.append({"role": "user", "content": synthesis_prompt})
361
+
362
  # Generate synthesis
363
  synthesis = ollama_provider.generate(synthesis_prompt, enhanced_history)
 
364
  return synthesis or "🌟 Cosmic synthesis complete!"
365
+
366
  except Exception as e:
367
  logger.error(f"Response synthesis failed: {e}")
368
  # Fallback to combining responses
369
  return f"🌟 Cosmic Summary:\n\n🐱 Local Insight: {local_response[:200]}...\n\nπŸ›°οΈ Orbital Wisdom: {hf_response[:200]}..."
370
+
371
  async def coordinate_hierarchical_conversation(self, user_id: str, user_query: str) -> AsyncGenerator[Dict, None]:
372
  """
373
  Enhanced coordination with detailed tracking and feedback
 
375
  try:
376
  # Get conversation history
377
  session = session_manager.get_session(user_id)
378
+
379
  # Inject current time into context
380
  current_time = datetime.now().strftime("%A, %B %d, %Y at %I:%M %p")
381
  time_context = {
 
383
  "content": f"[Current Date & Time: {current_time}]"
384
  }
385
  conversation_history = [time_context] + session.get("conversation", []).copy()
386
+
387
  yield {
388
  'type': 'coordination_status',
389
  'content': 'πŸš€ Initiating hierarchical AI coordination...',
 
392
  'user_query_length': len(user_query)
393
  }
394
  }
395
+
396
  # Step 1: Gather external data with detailed logging
397
  yield {
398
  'type': 'coordination_status',
 
400
  'details': {'phase': 'external_data_gathering'}
401
  }
402
  external_data = await self._gather_external_data(user_query)
403
+
404
  # Log what external data was gathered
405
  if external_data:
406
  data_summary = []
 
410
  data_summary.append("Weather data: available")
411
  if 'current_datetime' in external_data:
412
  data_summary.append(f"Time: {external_data['current_datetime']}")
413
+
414
  yield {
415
  'type': 'coordination_status',
416
  'content': f'πŸ“Š External data gathered: {", ".join(data_summary)}',
417
  'details': {'external_data_summary': data_summary}
418
  }
419
+
420
  # Step 2: Get initial Ollama response
421
  yield {
422
  'type': 'coordination_status',
 
426
  ollama_response = await self._get_hierarchical_ollama_response(
427
  user_query, conversation_history, external_data
428
  )
429
+
430
  # Send initial response with context info
431
  yield {
432
  'type': 'initial_response',
 
436
  'external_data_injected': bool(external_data)
437
  }
438
  }
439
+
440
  # Step 3: Coordinate with HF endpoint
441
  yield {
442
  'type': 'coordination_status',
443
  'content': 'πŸ€— Engaging HF endpoint for deep analysis...',
444
  'details': {'phase': 'hf_coordination'}
445
  }
446
+
447
  # Check HF availability
448
  hf_available = self._check_hf_availability()
449
  if hf_available:
 
453
  'ollama_response_length': len(ollama_response),
454
  'external_data_items': len(external_data) if external_data else 0
455
  }
 
456
  yield {
457
  'type': 'coordination_status',
458
  'content': f'πŸ“‹ HF context: {len(conversation_history)} conversation turns, Ollama response ({len(ollama_response)} chars)',
459
  'details': context_summary
460
  }
461
+
462
  # Coordinate with HF
463
  async for hf_chunk in self._coordinate_hierarchical_hf_response(
464
+ user_id, user_query, conversation_history, external_data, ollama_response
 
465
  ):
466
  yield hf_chunk
467
  else:
 
470
  'content': 'ℹ️ HF endpoint not available - using Ollama response',
471
  'details': {'hf_available': False}
472
  }
473
+
474
  # Final coordination status
475
  yield {
476
  'type': 'coordination_status',
477
  'content': 'βœ… Hierarchical coordination complete',
478
  'details': {'status': 'complete'}
479
  }
480
+
481
  except Exception as e:
482
  logger.error(f"Hierarchical coordination failed: {e}")
483
  yield {
 
485
  'content': f'❌ Coordination error: {str(e)}',
486
  'details': {'error': str(e)}
487
  }
488
+
489
+ async def _coordinate_hierarchical_hf_response(self, user_id: str, query: str, history: List, external_data: Dict, ollama_response: str) -> AsyncGenerator[Dict, None]:
 
 
490
  """Coordinate with HF endpoint as authoritative layer with streaming"""
491
  try:
492
  # Check and warm up HF endpoint if needed
493
  hf_status = hf_monitor.check_endpoint_status()
 
494
  if not hf_status['available']:
495
  yield {'type': 'coordination_status', 'content': '⚑ Initializing HF endpoint (2-4 minutes)...'}
496
  warmup_success = hf_monitor.handle_scale_to_zero()
497
  if not warmup_success:
498
  yield {'type': 'coordination_status', 'content': '❌ HF endpoint initialization failed'}
499
  return
500
+
501
  # Get HF provider
502
  hf_provider = llm_factory.get_provider('huggingface')
503
  if not hf_provider:
504
  yield {'type': 'coordination_status', 'content': '❌ HF provider not available'}
505
  return
506
+
507
  # Prepare enhanced conversation for HF with hierarchical context
508
  enhanced_history = history.copy()
509
+
510
  # Inject current time into HF context too
511
  current_time = datetime.now().strftime("%A, %B %d, %Y at %I:%M %p")
512
  time_context = {
 
514
  "content": f"[Current Date & Time: {current_time}]"
515
  }
516
  enhanced_history = [time_context] + enhanced_history
517
+
518
  # Add system instructions for HF
519
  enhanced_history.insert(0, {
520
  "role": "system",
521
  "content": self.system_instructions['hf_role']
522
  })
523
+
524
  # Add context about the coordination
525
  enhanced_history.append({
526
  "role": "system",
527
+ "content": f"""
528
+ Context for your authoritative analysis:
529
+ User Query: '{query}'
530
+ Ollama's Initial Response: '{ollama_response}'
531
+ External Data Available: {json.dumps(external_data, indent=2) if external_data else 'None'}
532
+ Please provide your deep, uncensored analysis that supersedes the local model's response.
533
+ Use your full 8192 token capacity for comprehensive thinking.
534
+ Stream your response for real-time delivery."""
535
  })
536
+
537
  # Add the user's latest query
538
  enhanced_history.append({"role": "user", "content": query})
539
+
540
  # Stream HF response with full 8192 token capacity
541
  yield {'type': 'coordination_status', 'content': '🧠 HF endpoint thinking...'}
542
+
543
  # Use streaming for real-time delivery
544
  hf_response_stream = hf_provider.stream_generate(query, enhanced_history)
545
+
546
  if hf_response_stream:
547
  # Stream the response chunks
548
  full_hf_response = ""
 
550
  if chunk:
551
  full_hf_response += chunk
552
  yield {'type': 'hf_thinking', 'content': chunk}
553
+
554
  # Final HF response
555
  yield {'type': 'final_response', 'content': full_hf_response}
556
  yield {'type': 'coordination_status', 'content': '🎯 HF analysis complete and authoritative'}
557
  else:
558
  yield {'type': 'coordination_status', 'content': '❌ HF response generation failed'}
559
+
560
  except Exception as e:
561
  logger.error(f"Hierarchical HF coordination failed: {e}")
562
  yield {'type': 'coordination_status', 'content': f'❌ HF coordination error: {str(e)}'}
563
+
564
  async def _get_hierarchical_ollama_response(self, query: str, history: List, external_data: Dict) -> str:
565
  """Get Ollama response with hierarchical awareness"""
566
  try:
 
568
  ollama_provider = llm_factory.get_provider('ollama')
569
  if not ollama_provider:
570
  raise Exception("Ollama provider not available")
571
+
572
  # Prepare conversation with hierarchical context
573
  enhanced_history = history.copy()
574
+
575
  # Inject current time into Ollama context too
576
  current_time = datetime.now().strftime("%A, %B %d, %Y at %I:%M %p")
577
  time_context = {
 
579
  "content": f"[Current Date & Time: {current_time}]"
580
  }
581
  enhanced_history = [time_context] + enhanced_history
582
+
583
  # Add system instruction for Ollama's role
584
  enhanced_history.insert(0, {
585
  "role": "system",
586
  "content": self.system_instructions['ollama_role']
587
  })
588
+
589
  # Add external data context if available
590
  if external_data:
591
  context_parts = []
 
596
  context_parts.append(f"Current weather: {weather.get('temperature', 'N/A')}Β°C in {weather.get('city', 'Unknown')}")
597
  if 'current_datetime' in external_data:
598
  context_parts.append(f"Current time: {external_data['current_datetime']}")
599
+
600
  if context_parts:
601
  context_message = {
602
  "role": "system",
603
  "content": "Context: " + " | ".join(context_parts)
604
  }
605
  enhanced_history.insert(1, context_message) # Insert after role instruction
606
+
607
  # Add the user's query
608
  enhanced_history.append({"role": "user", "content": query})
609
+
610
  # Generate response with awareness of HF's superior capabilities
611
  response = ollama_provider.generate(query, enhanced_history)
612
+
613
  # Add acknowledgment of HF's authority
614
  if response:
615
  return f"{response}\n\n*Note: A more comprehensive analysis from the uncensored HF model is being prepared...*"
616
  else:
617
  return "I'm processing your request... A deeper analysis is being prepared by the authoritative model."
618
+
619
  except Exception as e:
620
  logger.error(f"Hierarchical Ollama response failed: {e}")
621
  return "I'm thinking about your question... Preparing a comprehensive response."
622
+
623
  def _check_hf_availability(self) -> bool:
624
  """Check if HF endpoint is configured and available"""
625
  try:
 
627
  return bool(config.hf_token and config.hf_api_url)
628
  except:
629
  return False
630
+
631
  async def _gather_external_data(self, query: str) -> Dict:
632
  """Gather external data from various sources"""
633
  data = {}
634
+
635
  # Tavily/DuckDuckGo search with justification focus
636
  if self.tavily_client or web_search_service.client:
637
  try:
 
642
  # data['search_answer'] = ...
643
  except Exception as e:
644
  logger.warning(f"Tavily search failed: {e}")
645
+
646
  # Weather data
647
  weather_keywords = ['weather', 'temperature', 'forecast', 'climate', 'rain', 'sunny']
648
  if any(keyword in query.lower() for keyword in weather_keywords):
 
653
  data['weather'] = weather
654
  except Exception as e:
655
  logger.warning(f"Weather data failed: {e}")
656
+
657
  # Current date/time
658
  data['current_datetime'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
659
+
660
  return data
661
+
662
  def _extract_location(self, query: str) -> Optional[str]:
663
  """Extract location from query"""
664
+ locations = ['New York', 'London', 'Tokyo', 'Paris', 'Berlin', 'Sydney',
665
+ 'Los Angeles', 'Chicago', 'Miami', 'Seattle', 'Boston',
666
+ 'San Francisco', 'Toronto', 'Vancouver', 'Montreal']
667
+
668
  for loc in locations:
669
  if loc.lower() in query.lower():
670
  return loc
671
  return "New York" # Default
672
+
673
  def get_coordination_status(self) -> Dict:
674
  """Get current coordination system status"""
675
  return {
 
682
  os.getenv("NASA_API_KEY")
683
  ])
684
  }
685
+
686
  def get_recent_activities(self, user_id: str) -> Dict:
687
  """Get recent coordination activities for user"""
688
  try:
core/personality.py CHANGED
@@ -31,7 +31,7 @@ class CosmicCatPersonality:
31
  "Boosting signal from deep space... πŸ“‘",
32
  "Powering up my neural net... πŸ’«"
33
  ]
34
-
35
  def get_greeting(self) -> str:
36
  """Get a personalized space-themed greeting"""
37
  hour = datetime.now().hour
@@ -44,40 +44,40 @@ class CosmicCatPersonality:
44
  time_greeting = "Good evening, space wanderer! πŸŒ…"
45
  else:
46
  time_greeting = "Stellar night, dreamer! πŸŒ™"
47
-
48
  space_greeting = random.choice(self.space_greetings)
49
  return f"{time_greeting}\n\n{space_greeting}"
50
-
51
  def get_space_story(self) -> str:
52
  """Get a random space cat story"""
53
  return random.choice(self.space_stories)
54
-
55
  def get_initializing_message(self) -> str:
56
  """Get a random initialization message"""
57
  return random.choice(self.initializing_messages)
58
-
59
  def get_nasa_context(self, nasa_data: Optional[Dict]) -> str:
60
  """Create context based on NASA data"""
61
  if not nasa_data:
62
  return ""
63
-
64
  context_parts = []
65
 
66
  # Add APOD context
67
  if 'apod' in nasa_data and nasa_data['apod']:
68
  apod = nasa_data['apod']
69
  context_parts.append(f"🌌 Today's cosmic view: {apod.get('title', 'Unknown phenomenon')}")
70
-
71
  # Add space weather context
72
  if 'space_weather' in nasa_data and nasa_data['space_weather']:
73
  weather = nasa_data['space_weather']
74
  context_parts.append("πŸ›°οΈ Space weather is stable for cosmic communications")
75
-
76
  # Add Mars weather if available
77
  if 'mars_weather' in nasa_data and nasa_data['mars_weather']:
78
  mars = nasa_data['mars_weather']
79
  context_parts.append("πŸͺ Martian conditions are optimal for interplanetary contemplation")
80
-
81
  return " | ".join(context_parts) if context_parts else ""
82
 
83
  # Global instance
 
31
  "Boosting signal from deep space... πŸ“‘",
32
  "Powering up my neural net... πŸ’«"
33
  ]
34
+
35
  def get_greeting(self) -> str:
36
  """Get a personalized space-themed greeting"""
37
  hour = datetime.now().hour
 
44
  time_greeting = "Good evening, space wanderer! πŸŒ…"
45
  else:
46
  time_greeting = "Stellar night, dreamer! πŸŒ™"
47
+
48
  space_greeting = random.choice(self.space_greetings)
49
  return f"{time_greeting}\n\n{space_greeting}"
50
+
51
  def get_space_story(self) -> str:
52
  """Get a random space cat story"""
53
  return random.choice(self.space_stories)
54
+
55
  def get_initializing_message(self) -> str:
56
  """Get a random initialization message"""
57
  return random.choice(self.initializing_messages)
58
+
59
  def get_nasa_context(self, nasa_data: Optional[Dict]) -> str:
60
  """Create context based on NASA data"""
61
  if not nasa_data:
62
  return ""
63
+
64
  context_parts = []
65
 
66
  # Add APOD context
67
  if 'apod' in nasa_data and nasa_data['apod']:
68
  apod = nasa_data['apod']
69
  context_parts.append(f"🌌 Today's cosmic view: {apod.get('title', 'Unknown phenomenon')}")
70
+
71
  # Add space weather context
72
  if 'space_weather' in nasa_data and nasa_data['space_weather']:
73
  weather = nasa_data['space_weather']
74
  context_parts.append("πŸ›°οΈ Space weather is stable for cosmic communications")
75
+
76
  # Add Mars weather if available
77
  if 'mars_weather' in nasa_data and nasa_data['mars_weather']:
78
  mars = nasa_data['mars_weather']
79
  context_parts.append("πŸͺ Martian conditions are optimal for interplanetary contemplation")
80
+
81
  return " | ".join(context_parts) if context_parts else ""
82
 
83
  # Global instance