rdune71 commited on
Commit
b5d5e39
·
1 Parent(s): 03f412b

Implement enhanced debug panel with toggle controls and detailed status tracking

Browse files
app.py CHANGED
@@ -10,31 +10,29 @@ from utils.config import config
10
  from core.llm import send_to_ollama, send_to_hf
11
  from core.session import session_manager
12
  from core.memory import check_redis_health
 
 
 
 
 
13
 
14
  st.set_page_config(page_title="AI Life Coach", page_icon="🧠", layout="wide")
15
 
16
  # Initialize session state
17
  if "messages" not in st.session_state:
18
  st.session_state.messages = []
19
-
20
  if "last_error" not in st.session_state:
21
  st.session_state.last_error = ""
22
-
23
  if "last_ollama_call_success" not in st.session_state:
24
  st.session_state.last_ollama_call_success = None
25
-
26
  if "last_ollama_call_time" not in st.session_state:
27
  st.session_state.last_ollama_call_time = ""
28
-
29
  if "last_ollama_response_preview" not in st.session_state:
30
  st.session_state.last_ollama_response_preview = ""
31
-
32
  if "last_hf_call_success" not in st.session_state:
33
  st.session_state.last_hf_call_success = None
34
-
35
  if "last_hf_call_time" not in st.session_state:
36
  st.session_state.last_hf_call_time = ""
37
-
38
  if "last_hf_response_preview" not in st.session_state:
39
  st.session_state.last_hf_response_preview = ""
40
 
@@ -42,7 +40,7 @@ if "last_hf_response_preview" not in st.session_state:
42
  with st.sidebar:
43
  st.title("AI Life Coach")
44
  st.markdown("Your personal AI-powered life development assistant")
45
-
46
  # Model selection
47
  model_options = {
48
  "Mistral 7B (Local)": "mistral:latest",
@@ -55,54 +53,153 @@ with st.sidebar:
55
  index=0
56
  )
57
  st.session_state.selected_model = model_options[selected_model_name]
58
-
59
  # Ollama URL input
60
  st.session_state.ngrok_url = st.text_input(
61
  "Ollama Server URL",
62
  value=st.session_state.get("ngrok_url", "http://localhost:11434"),
63
  help="Enter the URL to your Ollama server"
64
  )
65
-
66
  # Conversation history
67
  st.subheader("Conversation History")
68
  if st.button("Clear History"):
69
  st.session_state.messages = []
70
  st.success("History cleared!")
71
-
72
- # Debug info
73
- with st.sidebar.expander("🔧 Debug Info"):
74
- st.write(f"**OLLAMA_HOST**: {st.session_state.ngrok_url}")
75
- st.write(f"**Selected Model**: {st.session_state.selected_model}")
76
- st.write(f"Fallback Mode: {'✅ On' if config.use_fallback else '❌ Off'}")
77
- st.write(f"Redis Status: {'✅ Healthy' if check_redis_health() else '⚠️ Unavailable'}")
78
- st.write(f"Env Detected As: {'☁️ HF Space' if config.is_hf_space else '🏠 Local'}")
79
- st.write(f"HF Token Set: {'✅ Yes' if config.hf_token else '❌ No'}")
80
-
81
- if st.session_state.last_error:
82
- st.warning(f"Last Error: {st.session_state.last_error}")
83
-
84
- # Ollama API Call Tracking
85
- if st.session_state.last_ollama_call_success is not None:
86
- status_icon = "✅ Success" if st.session_state.last_ollama_call_success else "❌ Failed"
87
- st.write(f"Last Ollama Call: {status_icon}")
88
- st.write(f"At: {st.session_state.last_ollama_call_time}")
89
- if st.session_state.last_ollama_response_preview:
90
- st.code(st.session_state.last_ollama_response_preview[:200] + ("..." if len(st.session_state.last_ollama_response_preview) > 200 else ""), language="text")
91
-
92
- # Hugging Face API Call Tracking
93
- if st.session_state.last_hf_call_success is not None:
94
- status_icon = " Success" if st.session_state.last_hf_call_success else "❌ Failed"
95
- st.write(f"Last HF Call: {status_icon}")
96
- st.write(f"At: {st.session_state.last_hf_call_time}")
97
- if st.session_state.last_hf_response_preview:
98
- st.code(st.session_state.last_hf_response_preview[:200] + ("..." if len(st.session_state.last_hf_response_preview) > 200 else ""), language="text")
99
-
100
- # Manual Refresh Button
101
- if st.button("🔄 Refresh Ollama Status"):
102
- from services.ollama_monitor import check_ollama_status
103
- status = check_ollama_status()
104
- # Fix Streamlit toast issue - replace with compatible function
105
- st.sidebar.info(f"Ollama Status: {'Running' if status['running'] else 'Unavailable'}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
 
107
  # Main chat interface
108
  st.title("🧠 AI Life Coach")
@@ -129,32 +226,31 @@ if send_button and user_input.strip():
129
  # Display user message
130
  with st.chat_message("user"):
131
  st.markdown(user_input)
132
-
133
  # Add user message to history
134
  st.session_state.messages.append({"role": "user", "content": user_input})
135
-
136
  # Reset error state
137
  st.session_state.last_error = ""
138
-
139
  # Get conversation history
140
  user_session = session_manager.get_session("default_user")
141
  conversation = user_session.get("conversation", [])
142
  conversation_history = conversation[-5:] # Last 5 messages
143
  conversation_history.append({"role": "user", "content": user_input})
144
-
145
  # Send to backend
146
  with st.chat_message("assistant"):
147
  with st.spinner("AI Coach is thinking..."):
148
  ai_response = None
149
  backend_used = ""
150
  error_msg = ""
151
-
152
  # Try Ollama first if not falling back
153
  if not config.use_fallback:
154
  try:
155
  ai_response = send_to_ollama(
156
- user_input, conversation_history,
157
- st.session_state.ngrok_url, st.session_state.selected_model
158
  )
159
  backend_used = "Ollama"
160
  # Capture success metadata
@@ -167,7 +263,7 @@ if send_button and user_input.strip():
167
  st.session_state.last_ollama_call_success = False
168
  st.session_state.last_ollama_call_time = str(datetime.utcnow())
169
  st.session_state.last_ollama_response_preview = str(e)[:200]
170
-
171
  # Fallback to Hugging Face if not ai_response and config.hf_token
172
  if not ai_response and config.hf_token:
173
  try:
@@ -183,7 +279,7 @@ if send_button and user_input.strip():
183
  st.session_state.last_hf_call_success = False
184
  st.session_state.last_hf_call_time = str(datetime.utcnow())
185
  st.session_state.last_hf_response_preview = str(e)[:200]
186
-
187
  if ai_response:
188
  st.markdown(f"{ai_response}")
189
  # Update conversation history
@@ -197,6 +293,6 @@ if send_button and user_input.strip():
197
  else:
198
  st.error("Failed to get response from both providers.")
199
  st.session_state.last_error = error_msg or "No response from either provider"
200
-
201
  # Clear input by forcing rerun
202
  st.experimental_rerun()
 
10
  from core.llm import send_to_ollama, send_to_hf
11
  from core.session import session_manager
12
  from core.memory import check_redis_health
13
+ import logging
14
+
15
+ # Set up logging
16
+ logging.basicConfig(level=logging.INFO)
17
+ logger = logging.getLogger(__name__)
18
 
19
  st.set_page_config(page_title="AI Life Coach", page_icon="🧠", layout="wide")
20
 
21
  # Initialize session state
22
  if "messages" not in st.session_state:
23
  st.session_state.messages = []
 
24
  if "last_error" not in st.session_state:
25
  st.session_state.last_error = ""
 
26
  if "last_ollama_call_success" not in st.session_state:
27
  st.session_state.last_ollama_call_success = None
 
28
  if "last_ollama_call_time" not in st.session_state:
29
  st.session_state.last_ollama_call_time = ""
 
30
  if "last_ollama_response_preview" not in st.session_state:
31
  st.session_state.last_ollama_response_preview = ""
 
32
  if "last_hf_call_success" not in st.session_state:
33
  st.session_state.last_hf_call_success = None
 
34
  if "last_hf_call_time" not in st.session_state:
35
  st.session_state.last_hf_call_time = ""
 
36
  if "last_hf_response_preview" not in st.session_state:
37
  st.session_state.last_hf_response_preview = ""
38
 
 
40
  with st.sidebar:
41
  st.title("AI Life Coach")
42
  st.markdown("Your personal AI-powered life development assistant")
43
+
44
  # Model selection
45
  model_options = {
46
  "Mistral 7B (Local)": "mistral:latest",
 
53
  index=0
54
  )
55
  st.session_state.selected_model = model_options[selected_model_name]
56
+
57
  # Ollama URL input
58
  st.session_state.ngrok_url = st.text_input(
59
  "Ollama Server URL",
60
  value=st.session_state.get("ngrok_url", "http://localhost:11434"),
61
  help="Enter the URL to your Ollama server"
62
  )
63
+
64
  # Conversation history
65
  st.subheader("Conversation History")
66
  if st.button("Clear History"):
67
  st.session_state.messages = []
68
  st.success("History cleared!")
69
+
70
+ # Enhanced Debug Panel
71
+ with st.expander("🔍 Advanced Debug", expanded=False):
72
+ st.subheader("System Controls")
73
+
74
+ # Fallback Mode Toggle
75
+ fallback_mode = st.checkbox(
76
+ "Enable Fallback Mode",
77
+ value=config.use_fallback,
78
+ help="Enable automatic fallback between providers"
79
+ )
80
+
81
+ # HF Endpoint Control
82
+ hf_enabled = st.checkbox(
83
+ "Enable HF Deep Analysis",
84
+ value=bool(config.hf_token),
85
+ help="Enable Hugging Face endpoint coordination"
86
+ )
87
+
88
+ # Web Search Toggle
89
+ web_search_enabled = st.checkbox(
90
+ "Enable Web Search",
91
+ value=bool(os.getenv("TAVILY_API_KEY")),
92
+ help="Enable Tavily/DDG web search integration"
93
+ )
94
+
95
+ st.subheader("Provider Status")
96
+
97
+ # Ollama Status
98
+ try:
99
+ from services.ollama_monitor import check_ollama_status
100
+ ollama_status = check_ollama_status()
101
+ if ollama_status.get("running"):
102
+ st.success(f"🦙 Ollama: Running ({ollama_status.get('model_loaded', 'Unknown')})")
103
+ else:
104
+ st.error("🦙 Ollama: Unavailable")
105
+ except Exception as e:
106
+ st.warning(f"🦙 Ollama: Status check failed")
107
+
108
+ # HF Endpoint Status
109
+ try:
110
+ from services.hf_endpoint_monitor import hf_monitor
111
+ hf_status = hf_monitor.get_status_summary()
112
+ if "🟢" in hf_status:
113
+ st.success(f"🤗 HF Endpoint: {hf_status.replace('🟢 ', '')}")
114
+ elif "🟡" in hf_status:
115
+ st.warning(f"🤗 HF Endpoint: {hf_status.replace('🟡 ', '')}")
116
+ else:
117
+ st.error(f"🤗 HF Endpoint: {hf_status.replace('🔴 ', '')}")
118
+ except Exception as e:
119
+ st.warning("🤗 HF Endpoint: Status check failed")
120
+
121
+ # Redis Status
122
+ redis_healthy = check_redis_health()
123
+ if redis_healthy:
124
+ st.success("💾 Redis: Connected")
125
+ else:
126
+ st.error("💾 Redis: Disconnected")
127
+
128
+ st.subheader("External Services")
129
+
130
+ # Web Search Status
131
+ if os.getenv("TAVILY_API_KEY"):
132
+ st.success("🔍 Web Search: Tavily API Active")
133
+ else:
134
+ st.info("🔍 Web Search: Not configured")
135
+
136
+ # Weather Service
137
+ if config.openweather_api_key:
138
+ st.success("🌤️ Weather: API Active")
139
+ else:
140
+ st.info("🌤️ Weather: Not configured")
141
+
142
+ # Session Stats
143
+ try:
144
+ user_session = session_manager.get_session("default_user")
145
+ conversation_length = len(user_session.get("conversation", []))
146
+ st.info(f"💬 Conversation Length: {conversation_length} messages")
147
+ except:
148
+ st.info("💬 Session: Not initialized")
149
+
150
+ # Real-time Web Search Status
151
+ st.subheader("Web Search Activity")
152
+
153
+ # Recent searches (if tracking enabled)
154
+ if 'recent_searches' in st.session_state:
155
+ for search in st.session_state.recent_searches[-3:]: # Last 3 searches
156
+ st.caption(f"🔍 {search['query'][:30]}... ({search['timestamp']})")
157
+ else:
158
+ st.info("No recent searches")
159
+
160
+ # Search test button
161
+ if st.button("🧪 Test Web Search"):
162
+ try:
163
+ from tavily import TavilyClient
164
+ if os.getenv("TAVILY_API_KEY"):
165
+ tavily = TavilyClient(api_key=os.getenv("TAVILY_API_KEY"))
166
+ test_result = tavily.search("AI life coach benefits", max_results=1)
167
+ st.success("✅ Web search working")
168
+ if test_result.get('results'):
169
+ st.caption(f"Sample: {test_result['results'][0].get('title', 'No title')}")
170
+ else:
171
+ st.warning("Web API key not configured")
172
+ except Exception as e:
173
+ st.error(f"❌ Web search test failed: {e}")
174
+
175
+ # Enhanced Configuration Display
176
+ st.subheader("Configuration Details")
177
+
178
+ # Provider Configuration
179
+ st.caption(f"**Primary Provider**: Ollama ({config.local_model_name})")
180
+ if config.hf_token:
181
+ st.caption(f"**Secondary Provider**: Hugging Face")
182
+ st.caption(f"**HF Endpoint**: {config.hf_api_url}")
183
+
184
+ # Environment Detection
185
+ env_type = "☁️ HF Space" if config.is_hf_space else "🏠 Local"
186
+ st.caption(f"**Environment**: {env_type}")
187
+
188
+ # Feature Flags
189
+ features = []
190
+ if config.use_fallback:
191
+ features.append("Fallback Mode")
192
+ if os.getenv("TAVILY_API_KEY"):
193
+ features.append("Web Search")
194
+ if config.openweather_api_key:
195
+ features.append("Weather Data")
196
+ if config.hf_token:
197
+ features.append("Deep Analysis")
198
+
199
+ if features:
200
+ st.caption(f"**Active Features**: {', '.join(features)}")
201
+ else:
202
+ st.caption("**Active Features**: None")
203
 
204
  # Main chat interface
205
  st.title("🧠 AI Life Coach")
 
226
  # Display user message
227
  with st.chat_message("user"):
228
  st.markdown(user_input)
229
+
230
  # Add user message to history
231
  st.session_state.messages.append({"role": "user", "content": user_input})
232
+
233
  # Reset error state
234
  st.session_state.last_error = ""
235
+
236
  # Get conversation history
237
  user_session = session_manager.get_session("default_user")
238
  conversation = user_session.get("conversation", [])
239
  conversation_history = conversation[-5:] # Last 5 messages
240
  conversation_history.append({"role": "user", "content": user_input})
241
+
242
  # Send to backend
243
  with st.chat_message("assistant"):
244
  with st.spinner("AI Coach is thinking..."):
245
  ai_response = None
246
  backend_used = ""
247
  error_msg = ""
248
+
249
  # Try Ollama first if not falling back
250
  if not config.use_fallback:
251
  try:
252
  ai_response = send_to_ollama(
253
+ user_input, conversation_history, st.session_state.ngrok_url, st.session_state.selected_model
 
254
  )
255
  backend_used = "Ollama"
256
  # Capture success metadata
 
263
  st.session_state.last_ollama_call_success = False
264
  st.session_state.last_ollama_call_time = str(datetime.utcnow())
265
  st.session_state.last_ollama_response_preview = str(e)[:200]
266
+
267
  # Fallback to Hugging Face if not ai_response and config.hf_token
268
  if not ai_response and config.hf_token:
269
  try:
 
279
  st.session_state.last_hf_call_success = False
280
  st.session_state.last_hf_call_time = str(datetime.utcnow())
281
  st.session_state.last_hf_response_preview = str(e)[:200]
282
+
283
  if ai_response:
284
  st.markdown(f"{ai_response}")
285
  # Update conversation history
 
293
  else:
294
  st.error("Failed to get response from both providers.")
295
  st.session_state.last_error = error_msg or "No response from either provider"
296
+
297
  # Clear input by forcing rerun
298
  st.experimental_rerun()
core/coordinator.py CHANGED
@@ -181,6 +181,33 @@ class AICoordinator:
181
  logger.error(f"HF response failed: {e}")
182
  return None
183
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  def _enhance_query_with_data(self, query: str, data: Dict) -> str:
185
  """Enhance query with gathered external data"""
186
  if not data:
 
181
  logger.error(f"HF response failed: {e}")
182
  return None
183
 
184
+ def get_coordination_status(self) -> Dict:
185
+ """Get current coordination system status"""
186
+ return {
187
+ 'tavily_available': self.tavily_client is not None,
188
+ 'weather_available': weather_service.api_key is not None,
189
+ 'web_search_enabled': self.tavily_client is not None,
190
+ 'external_apis_configured': any([
191
+ weather_service.api_key,
192
+ os.getenv("TAVILY_API_KEY"),
193
+ os.getenv("NASA_API_KEY")
194
+ ])
195
+ }
196
+
197
+ def get_recent_activities(self, user_id: str) -> Dict:
198
+ """Get recent coordination activities for user"""
199
+ try:
200
+ session = session_manager.get_session(user_id)
201
+ coord_stats = session.get('ai_coordination', {})
202
+ return {
203
+ 'last_request': coord_stats.get('last_coordination'),
204
+ 'requests_processed': coord_stats.get('requests_processed', 0),
205
+ 'ollama_responses': coord_stats.get('ollama_responses', 0),
206
+ 'hf_responses': coord_stats.get('hf_responses', 0)
207
+ }
208
+ except:
209
+ return {}
210
+
211
  def _enhance_query_with_data(self, query: str, data: Dict) -> str:
212
  """Enhance query with gathered external data"""
213
  if not data:
debug_dashboard_test.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+ from pathlib import Path
3
+
4
+ # Add project root to path
5
+ project_root = Path(__file__).parent
6
+ sys.path.append(str(project_root))
7
+
8
+ from services.hf_endpoint_monitor import hf_monitor
9
+ from core.coordinator import coordinator
10
+ from utils.config import config
11
+ import os
12
+
13
+ def test_debug_features():
14
+ """Test the enhanced debug features"""
15
+ print("=== Debug Dashboard Feature Test ===")
16
+ print()
17
+
18
+ # Test HF Endpoint Monitor Enhanced Features
19
+ print("1. Testing HF Endpoint Monitor Enhanced Features:")
20
+ try:
21
+ # Basic status
22
+ basic_status = hf_monitor.get_status_summary()
23
+ print(f" Basic Status: {basic_status}")
24
+
25
+ # Detailed status
26
+ detailed_status = hf_monitor.get_detailed_status()
27
+ print(f" Detailed Status Keys: {list(detailed_status.keys())}")
28
+
29
+ # Performance metrics
30
+ perf_metrics = hf_monitor.get_performance_metrics()
31
+ print(f" Performance Metrics: {perf_metrics}")
32
+
33
+ print(" ✅ HF Endpoint Monitor Enhanced Features Working")
34
+ except Exception as e:
35
+ print(f" ❌ HF Endpoint Monitor Test Failed: {e}")
36
+
37
+ print()
38
+
39
+ # Test Coordinator Status Tracking
40
+ print("2. Testing Coordinator Status Tracking:")
41
+ try:
42
+ # Coordination status
43
+ coord_status = coordinator.get_coordination_status()
44
+ print(f" Coordination Status: {coord_status}")
45
+
46
+ # Recent activities (test with demo user)
47
+ recent_activities = coordinator.get_recent_activities("demo_user")
48
+ print(f" Recent Activities Keys: {list(recent_activities.keys())}")
49
+
50
+ print(" ✅ Coordinator Status Tracking Working")
51
+ except Exception as e:
52
+ print(f" ❌ Coordinator Status Tracking Test Failed: {e}")
53
+
54
+ print()
55
+
56
+ # Test Configuration Display
57
+ print("3. Testing Configuration Display:")
58
+ try:
59
+ print(f" Environment Type: {'HF Space' if config.is_hf_space else 'Local'}")
60
+ print(f" Fallback Mode: {config.use_fallback}")
61
+ print(f" HF Token Available: {bool(config.hf_token)}")
62
+ print(f" Tavily API Key: {bool(os.getenv('TAVILY_API_KEY'))}")
63
+ print(f" OpenWeather API Key: {bool(config.openweather_api_key)}")
64
+
65
+ # Feature flags
66
+ features = []
67
+ if config.use_fallback:
68
+ features.append("Fallback Mode")
69
+ if os.getenv("TAVILY_API_KEY"):
70
+ features.append("Web Search")
71
+ if config.openweather_api_key:
72
+ features.append("Weather Data")
73
+ if config.hf_token:
74
+ features.append("Deep Analysis")
75
+
76
+ print(f" Active Features: {', '.join(features) if features else 'None'}")
77
+
78
+ print(" ✅ Configuration Display Working")
79
+ except Exception as e:
80
+ print(f" ❌ Configuration Display Test Failed: {e}")
81
+
82
+ print()
83
+ print("🎉 Debug Dashboard Feature Test Completed!")
84
+
85
+ if __name__ == "__main__":
86
+ test_debug_features()
services/hf_endpoint_monitor.py CHANGED
@@ -15,6 +15,10 @@ class HFEndpointMonitor:
15
  self.is_initialized = False
16
  self.last_check = 0
17
  self.check_interval = 60 # Check every minute
 
 
 
 
18
 
19
  def check_endpoint_status(self) -> Dict:
20
  """Check if HF endpoint is available and initialized"""
@@ -49,6 +53,61 @@ class HFEndpointMonitor:
49
  'timestamp': time.time()
50
  }
51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  def _is_endpoint_initialized(self, response) -> bool:
53
  """Determine if endpoint is fully initialized"""
54
  # If we get a model list, it's likely initialized
@@ -84,6 +143,7 @@ class HFEndpointMonitor:
84
  success = response.status_code in [200, 201]
85
  if success:
86
  self.is_initialized = True
 
87
  logger.info("✅ HF endpoint warmed up successfully")
88
  else:
89
  logger.warning(f"⚠️ HF endpoint warm-up response: {response.status_code}")
@@ -92,6 +152,7 @@ class HFEndpointMonitor:
92
 
93
  except Exception as e:
94
  logger.error(f"HF endpoint warm-up failed: {e}")
 
95
  return False
96
 
97
  def get_status_summary(self) -> str:
 
15
  self.is_initialized = False
16
  self.last_check = 0
17
  self.check_interval = 60 # Check every minute
18
+ self.warmup_count = 0
19
+ self.successful_requests = 0
20
+ self.failed_requests = 0
21
+ self.avg_response_time = 0
22
 
23
  def check_endpoint_status(self) -> Dict:
24
  """Check if HF endpoint is available and initialized"""
 
53
  'timestamp': time.time()
54
  }
55
 
56
+ def get_detailed_status(self) -> Dict:
57
+ """Get detailed HF endpoint status with metrics"""
58
+ try:
59
+ headers = {"Authorization": f"Bearer {self.hf_token}"}
60
+
61
+ # Get model info
62
+ model_response = requests.get(
63
+ f"{self.endpoint_url}/models",
64
+ headers=headers,
65
+ timeout=10
66
+ )
67
+
68
+ # Get endpoint info if available
69
+ endpoint_info = {}
70
+ try:
71
+ info_response = requests.get(
72
+ f"{self.endpoint_url}/info",
73
+ headers=headers,
74
+ timeout=10
75
+ )
76
+ if info_response.status_code == 200:
77
+ endpoint_info = info_response.json()
78
+ except:
79
+ pass
80
+
81
+ status_info = {
82
+ 'available': model_response.status_code == 200,
83
+ 'status_code': model_response.status_code,
84
+ 'initialized': self._is_endpoint_initialized(model_response),
85
+ 'endpoint_info': endpoint_info,
86
+ 'last_checked': time.time(),
87
+ 'warmup_attempts': getattr(self, 'warmup_attempts', 0),
88
+ 'is_warming_up': getattr(self, 'is_warming_up', False)
89
+ }
90
+
91
+ return status_info
92
+
93
+ except Exception as e:
94
+ return {
95
+ 'available': False,
96
+ 'status_code': None,
97
+ 'initialized': False,
98
+ 'error': str(e),
99
+ 'last_checked': time.time()
100
+ }
101
+
102
+ def get_performance_metrics(self) -> Dict:
103
+ """Get HF endpoint performance metrics"""
104
+ return {
105
+ 'warmup_count': getattr(self, 'warmup_count', 0),
106
+ 'successful_requests': getattr(self, 'successful_requests', 0),
107
+ 'failed_requests': getattr(self, 'failed_requests', 0),
108
+ 'average_response_time': getattr(self, 'avg_response_time', 0)
109
+ }
110
+
111
  def _is_endpoint_initialized(self, response) -> bool:
112
  """Determine if endpoint is fully initialized"""
113
  # If we get a model list, it's likely initialized
 
143
  success = response.status_code in [200, 201]
144
  if success:
145
  self.is_initialized = True
146
+ self.warmup_count += 1
147
  logger.info("✅ HF endpoint warmed up successfully")
148
  else:
149
  logger.warning(f"⚠️ HF endpoint warm-up response: {response.status_code}")
 
152
 
153
  except Exception as e:
154
  logger.error(f"HF endpoint warm-up failed: {e}")
155
+ self.failed_requests += 1
156
  return False
157
 
158
  def get_status_summary(self) -> str: