Spaces:
Paused
Paused
Automated deployment via API
Browse files
app.py
CHANGED
|
@@ -359,69 +359,94 @@ def upload_data():
|
|
| 359 |
|
| 360 |
from huggingface_hub import InferenceClient
|
| 361 |
|
| 362 |
-
# Initialize Inference Client
|
| 363 |
-
#
|
| 364 |
-
client = InferenceClient("
|
| 365 |
|
| 366 |
def generate_ai_response(query):
|
| 367 |
-
"""Generate AI response using
|
|
|
|
|
|
|
| 368 |
try:
|
| 369 |
-
# 1. Gather Context
|
| 370 |
current_temp = app_state.get_temperature()
|
| 371 |
optimal_low = CONFIG['TEMP_OPTIMAL_LOW']
|
| 372 |
optimal_high = CONFIG['TEMP_OPTIMAL_HIGH']
|
| 373 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 374 |
is_anomaly = app_state.is_anomaly
|
| 375 |
risk_score = app_state.anomaly_risk * 100
|
| 376 |
|
| 377 |
-
# 2. Construct System Prompt
|
| 378 |
system_prompt = f"""
|
| 379 |
-
|
| 380 |
-
|
| 381 |
-
-
|
| 382 |
-
- Energy
|
| 383 |
-
- Anomaly
|
| 384 |
|
| 385 |
INSTRUCTIONS:
|
| 386 |
-
|
| 387 |
-
|
| 388 |
-
|
| 389 |
-
- Be concise, professional, and helpful. Do not mention you are an AI model.
|
| 390 |
-
- Use formatting like **bold** for key metrics.
|
| 391 |
"""
|
| 392 |
|
| 393 |
-
#
|
| 394 |
-
messages = [
|
| 395 |
-
{"role": "user", "content": system_prompt + "\n\nUSER QUESTION: " + query}
|
| 396 |
-
]
|
| 397 |
-
|
| 398 |
try:
|
| 399 |
-
|
| 400 |
-
|
| 401 |
-
|
| 402 |
-
|
| 403 |
-
|
| 404 |
-
|
| 405 |
-
|
| 406 |
-
return
|
|
|
|
| 407 |
except Exception as api_err:
|
| 408 |
-
logger.warning(f"⚠️
|
| 409 |
-
|
| 410 |
|
| 411 |
except Exception as e:
|
| 412 |
-
logger.error(f"❌
|
| 413 |
-
|
| 414 |
-
fallback_temp = app_state.get_temperature()
|
| 415 |
-
if 'pour' in query.lower():
|
| 416 |
-
if 1410 <= fallback_temp <= 1430:
|
| 417 |
-
return f"✅ **POUR READY** (Offline Mode). Temp {fallback_temp:.1f}°C is optimal."
|
| 418 |
-
return f"⚠️ **HOLD POUR** (Offline Mode). Temp {fallback_temp:.1f}°C is out of range."
|
| 419 |
-
return f"🤖 **System Status**: Temp {fallback_temp:.1f}°C, Energy {app_state.get_energy():.1f}kWh. (Neural Network Unreachable, verifying safety protocols...)"
|
| 420 |
-
|
| 421 |
-
# ============================================================================
|
| 422 |
-
# 6. SOCKET.IO EVENTS
|
| 423 |
-
# ============================================================================
|
| 424 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 425 |
@socketio.on('connect')
|
| 426 |
def handle_connect():
|
| 427 |
"""Handle client connection"""
|
|
|
|
| 359 |
|
| 360 |
from huggingface_hub import InferenceClient
|
| 361 |
|
| 362 |
+
# Initialize Inference Client
|
| 363 |
+
# Using Phi-3 Mini for high reliability and low latency on public API
|
| 364 |
+
client = InferenceClient("microsoft/Phi-3-mini-4k-instruct")
|
| 365 |
|
| 366 |
def generate_ai_response(query):
|
| 367 |
+
"""Generate AI response using Phi-3 LLM with strict fallback"""
|
| 368 |
+
# Default Fallback (pre-calculated to always be available)
|
| 369 |
+
fallback_response = "⚠️ **Neural Link Unstable**. Falling back to local protocols."
|
| 370 |
try:
|
|
|
|
| 371 |
current_temp = app_state.get_temperature()
|
| 372 |
optimal_low = CONFIG['TEMP_OPTIMAL_LOW']
|
| 373 |
optimal_high = CONFIG['TEMP_OPTIMAL_HIGH']
|
| 374 |
+
|
| 375 |
+
# Smart Fallback Logic
|
| 376 |
+
if 'pour' in query.lower():
|
| 377 |
+
if 1410 <= current_temp <= 1430:
|
| 378 |
+
fallback_response = f"✅ **POUR READY** (Offline Mode). Current Temp {current_temp:.1f}°C is optimal."
|
| 379 |
+
else:
|
| 380 |
+
fallback_response = f"⚠️ **HOLD POUR** (Offline Mode). Current Temp {current_temp:.1f}°C is out of range ({optimal_low}-{optimal_high}°C)."
|
| 381 |
+
elif 'temp' in query.lower():
|
| 382 |
+
fallback_response = f"🌡️ **Offline Status**: {current_temp:.1f}°C. (Optimal: {optimal_low}-{optimal_high}°C)"
|
| 383 |
+
elif 'energy' in query.lower():
|
| 384 |
+
fallback_response = f"⚡ **Energy Status**: {app_state.get_energy():.1f} kWh."
|
| 385 |
+
|
| 386 |
+
# 1. Gather Context for Prompt
|
| 387 |
is_anomaly = app_state.is_anomaly
|
| 388 |
risk_score = app_state.anomaly_risk * 100
|
| 389 |
|
|
|
|
| 390 |
system_prompt = f"""
|
| 391 |
+
You are the IronGuard Foundry AI.
|
| 392 |
+
LIVE SENSOR DATA:
|
| 393 |
+
- Temp: {current_temp:.1f}°C (Target: {optimal_low}-{optimal_high})
|
| 394 |
+
- Energy: {app_state.get_energy():.1f} kWh
|
| 395 |
+
- Anomaly Risk: {risk_score:.1f}%
|
| 396 |
|
| 397 |
INSTRUCTIONS:
|
| 398 |
+
Answer the user's question using the LIVE SENSOR DATA.
|
| 399 |
+
If Temp > {CONFIG['TEMP_MAX']}, warn immediately.
|
| 400 |
+
Keep answers short and professional.
|
|
|
|
|
|
|
| 401 |
"""
|
| 402 |
|
| 403 |
+
# 2. Call API (Nested Try to catch API specific errors)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 404 |
try:
|
| 405 |
+
messages = [
|
| 406 |
+
{"role": "user", "content": system_prompt + "\nUSER: " + query}
|
| 407 |
+
]
|
| 408 |
+
response = ""
|
| 409 |
+
for message in client.chat_completion(messages, max_tokens=150, stream=True):
|
| 410 |
+
if message.choices and message.choices[0].delta.content:
|
| 411 |
+
response += message.choices[0].delta.content
|
| 412 |
+
return response if response else fallback_response
|
| 413 |
+
|
| 414 |
except Exception as api_err:
|
| 415 |
+
logger.warning(f"⚠️ API Error: {api_err}")
|
| 416 |
+
return fallback_response
|
| 417 |
|
| 418 |
except Exception as e:
|
| 419 |
+
logger.error(f"❌ Critical Logic Error: {e}")
|
| 420 |
+
return fallback_response
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 421 |
|
| 422 |
+
@app.route('/api/chat', methods=['POST'])
|
| 423 |
+
def chat():
|
| 424 |
+
"""AI Chat interface with fail-safe return"""
|
| 425 |
+
try:
|
| 426 |
+
data = request.json
|
| 427 |
+
query = data.get('query', '').lower()
|
| 428 |
+
|
| 429 |
+
# Guaranteed to return a string, never raises
|
| 430 |
+
response = generate_ai_response(query)
|
| 431 |
+
|
| 432 |
+
app_state.chat_history.append({
|
| 433 |
+
'user': query,
|
| 434 |
+
'bot': response,
|
| 435 |
+
'timestamp': datetime.now().isoformat()
|
| 436 |
+
})
|
| 437 |
+
|
| 438 |
+
return jsonify({
|
| 439 |
+
'response': response,
|
| 440 |
+
'confidence': 1.0, # Artificial confidence for UX
|
| 441 |
+
'timestamp': datetime.now().isoformat()
|
| 442 |
+
})
|
| 443 |
+
except Exception as e:
|
| 444 |
+
logger.error(f"❌ Critical Route Error: {e}")
|
| 445 |
+
# Absolute last resort JSON to prevent frontend 'System Error'
|
| 446 |
+
return jsonify({
|
| 447 |
+
'response': "⚠️ **System Critical**: Local fallback active. Please refresh console.",
|
| 448 |
+
'confidence': 0.0
|
| 449 |
+
})
|
| 450 |
@socketio.on('connect')
|
| 451 |
def handle_connect():
|
| 452 |
"""Handle client connection"""
|