Welly-code commited on
Commit
27f0c52
·
verified ·
1 Parent(s): c3b21fe

Upload main.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. main.py +154 -0
main.py ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import os
3
+ import signal
4
+ import logging
5
+ import threading
6
+ import asyncio
7
+ import time
8
+ from fastapi import FastAPI
9
+ import uvicorn
10
+ from telegram import Update
11
+ from telegram.ext import ApplicationBuilder, ContextTypes, MessageHandler, filters
12
+ from telegram.request import HTTPXRequest
13
+ from brain.ops_brain import OpsManagerAI
14
+ from brain.db_handler import StoreDB
15
+
16
+ # --- Configuration ---
17
+ logging.basicConfig(
18
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
19
+ level=logging.INFO
20
+ )
21
+ logger = logging.getLogger(__name__)
22
+
23
+ def get_required_env(var_name: str) -> str:
24
+ """Fetch a required environment variable or raise a clear error."""
25
+ value = os.getenv(var_name)
26
+ if not value or not value.strip():
27
+ raise RuntimeError(
28
+ f"Missing required environment variable: '{var_name}'. "
29
+ f"Please set it in your Secrets/Environment settings."
30
+ )
31
+ return value
32
+
33
+ # Load secrets
34
+ TELEGRAM_TOKEN = get_required_env("TELEGRAM_TOKEN")
35
+ GROQ_API_KEY = get_required_env("GROQ_API_KEY")
36
+ SUPABASE_URL = get_required_env("SUPABASE_URL")
37
+ SUPABASE_KEY = get_required_env("SUPABASE_KEY")
38
+
39
+ # --- Initialize AI & DB ---
40
+ def init_services():
41
+ try:
42
+ ai = OpsManagerAI(api_key=GROQ_API_KEY)
43
+ db = StoreDB(url=SUPABASE_URL, key=SUPABASE_KEY)
44
+ logger.info("AI and Database services initialized successfully.")
45
+ return ai, db
46
+ except Exception as e:
47
+ logger.critical(f"Service Initialization failed: {e}")
48
+ return None, None
49
+
50
+ ai_manager, db = init_services()
51
+
52
+ # --- Telegram Bot Logic ---
53
+ async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
54
+ text = update.message.text
55
+ if not text or not text.strip():
56
+ return
57
+
58
+ user = update.message.from_user
59
+ logger.info(f"Processing message from {user.first_name} (id={user.id}): {text}")
60
+
61
+ try:
62
+ if ai_manager is None or db is None:
63
+ raise RuntimeError("AI or Database services not initialized")
64
+
65
+ structured_data = ai_manager.process_telegram_message(text)
66
+
67
+ if not structured_data or not structured_data.get('store_id'):
68
+ logger.warning(f"AI could not extract a valid store_id from message: '{text}'")
69
+ await update.message.reply_text(
70
+ "⚠️ I couldn't extract a valid Store ID from your message. "
71
+ "Please make sure to mention the store location or ID in your report."
72
+ )
73
+ return
74
+
75
+ try:
76
+ db.save_report(structured_data)
77
+ except Exception as db_err:
78
+ logger.error(f"Database save failed: {db_err}")
79
+ await update.message.reply_text(
80
+ "❌ Critical Error: I analyzed your report, but the database rejected it.\n"
81
+ "The report has been queued locally, but it will NOT appear on the dashboard until the connection is fixed."
82
+ )
83
+ return
84
+
85
+ await update.message.reply_text(
86
+ f"✅ Report received for {structured_data.get('store_id', 'Unknown')}.\n"
87
+ f"Analysis: {structured_data.get('analysis', 'N/A')}\n"
88
+ f"Actions logged to Dashboard."
89
+ )
90
+
91
+ except Exception as e:
92
+ logger.error(f"Error in handler: {e}")
93
+ await update.message.reply_text(
94
+ "❌ Error processing report. Please ensure the format is correct."
95
+ )
96
+
97
+ # --- HF Health Check Server ---
98
+ app = FastAPI()
99
+
100
+ @app.get("/")
101
+ async def root():
102
+ bot_status = "Active" if ai_manager and db else "Degraded"
103
+ return {
104
+ "status": "Sovereign Ops Manager is Healthy",
105
+ "bot": bot_status
106
+ }
107
+
108
+ # --- Unified Engine ---
109
+ async def main():
110
+ stop_event = asyncio.Event()
111
+
112
+ loop = asyncio.get_running_loop()
113
+ for sig in (signal.SIGINT, signal.SIGTERM):
114
+ loop.add_signal_handler(sig, lambda: stop_event.set())
115
+
116
+ config = uvicorn.Config(app, host="0.0.0.0", port=7860, log_level="info")
117
+ server = uvicorn.Server(config)
118
+
119
+ server_task = asyncio.create_task(server.serve())
120
+ logger.info("HF Heartbeat Server initialized on port 7860.")
121
+
122
+ await asyncio.sleep(1.0)
123
+
124
+ request_client = HTTPXRequest(
125
+ connect_timeout=20.0, read_timeout=20.0, write_timeout=20.0, pool_timeout=20.0
126
+ )
127
+ bot_app = (
128
+ ApplicationBuilder()
129
+ .token(TELEGRAM_TOKEN)
130
+ .request(request_client)
131
+ .build()
132
+ )
133
+ bot_app.add_handler(MessageHandler(filters.TEXT & (~filters.COMMAND), handle_message))
134
+
135
+ await bot_app.initialize()
136
+ await bot_app.start()
137
+ await bot_app.updater.start_polling()
138
+ logger.info("Sovereign Bot is LIVE and polling.")
139
+
140
+ await stop_event.wait()
141
+
142
+ logger.info("Shutdown signal caught. Beginning cleanup...")
143
+ server.should_exit = True
144
+ await server_task
145
+ await bot_app.updater.stop()
146
+ await bot_app.stop()
147
+ await bot_app.shutdown()
148
+ logger.info("All services shut down gracefully.")
149
+
150
+ if __name__ == "__main__":
151
+ try:
152
+ asyncio.run(main())
153
+ except KeyboardInterrupt:
154
+ pass