FocusFlowAI / app.py
avaliev's picture
Update app.py
361a507 verified
raw
history blame
3.74 kB
"""
FocusFlow: AI Accountability Agent with Gradio 5 Interface.
Configurable via environment variables for HuggingFace Spaces or local use.
"""
import gradio as gr
import os
from dotenv import load_dotenv
from storage import TaskManager
from monitor import FileMonitor
from metrics import MetricsTracker
from voice import voice_generator
from linear_client import LinearClient
from core.pomodoro import PomodoroTimer
from core.focus_check import FocusMonitor
from ui.handlers import UIHandlers
from ui.layout import create_app
# Load environment variables
load_dotenv()
# Debug: Print Configuration
print("-" * 40)
print("πŸ”§ FOCUSFLOW CONFIGURATION")
print(f" LAUNCH_MODE: {os.getenv('LAUNCH_MODE', 'demo')}")
print(f" AI_PROVIDER: {os.getenv('AI_PROVIDER', 'openai')}")
print(f" MONITOR_INTERVAL: {os.getenv('MONITOR_INTERVAL', '30')}")
print(f" ENABLE_MCP: {os.getenv('ENABLE_MCP', 'true')}")
print(f" HF_SPACE: {'Yes' if os.getenv('SPACE_ID') or os.getenv('huggingface_space_id') else 'No'}")
# Masked Keys for safety
for key in ["OPENAI_API_KEY", "ANTHROPIC_API_KEY", "GEMINI_API_KEY", "LINEAR_API_KEY",
"DEMO_OPENAI_API_KEY", "DEMO_ANTHROPIC_API_KEY", "DEMO_GEMINI_API_KEY"]:
val = os.getenv(key)
status = f"Set ({val[:4]}...)" if val else "Not Set"
print(f" {key:<22}: {status}")
print("-" * 40)
# Import MCP tools to register them with Gradio
try:
import mcp_tools
MCP_AVAILABLE = True
except Exception as e:
print(f"⚠️ MCP tools not available: {e}")
MCP_AVAILABLE = False
# Configuration from environment
LAUNCH_MODE = os.getenv("LAUNCH_MODE", "demo").lower() # 'demo' or 'local'
AI_PROVIDER = os.getenv("AI_PROVIDER", "openai").lower() # 'openai', 'anthropic', or 'vllm'
MONITOR_INTERVAL = int(os.getenv("MONITOR_INTERVAL", "30")) # seconds
# Initialize Core Components
task_manager = TaskManager()
file_monitor = FileMonitor()
metrics_tracker = MetricsTracker()
linear_client = LinearClient()
# Initialize Logic Modules
focus_monitor = FocusMonitor(task_manager, file_monitor, metrics_tracker, voice_generator)
focus_monitor.set_launch_mode(LAUNCH_MODE)
pomodoro_timer = PomodoroTimer()
# Initialize UI Handlers
ui_handlers = UIHandlers(task_manager, file_monitor, metrics_tracker, focus_monitor, linear_client)
# Register cleanup handler
import atexit
import signal
import sys
def cleanup():
"""Cleanup resources on shutdown."""
print("🧹 Cleaning up resources...")
if file_monitor.is_running():
print(" Stopping file monitor...")
file_monitor.stop()
try:
print(" Closing Gradio app...")
app.close()
except Exception as e:
print(f" Error closing app: {e}")
atexit.register(cleanup)
def handle_sigterm(*args):
"""Handle SIGTERM signal from K8s/Docker."""
print("πŸ›‘ Received SIGTERM, initiating shutdown...")
sys.exit(0)
signal.signal(signal.SIGTERM, handle_sigterm)
# Create App
app = create_app(ui_handlers, pomodoro_timer, LAUNCH_MODE, AI_PROVIDER, MONITOR_INTERVAL)
if __name__ == "__main__":
# Enable MCP server if available
mcp_enabled = os.getenv("ENABLE_MCP", "true").lower() == "true"
try:
if MCP_AVAILABLE and mcp_enabled:
print("πŸ”— MCP Server enabled! Connect via Claude Desktop or other MCP clients.")
app.launch(server_name="0.0.0.0", server_port=7860, share=False, mcp_server=True)
else:
print("πŸ“± Running without MCP integration")
app.launch(server_name="0.0.0.0", server_port=7860, share=False)
except KeyboardInterrupt:
print("πŸ‘‹ FocusFlow stopped by user")
except Exception as e:
print(f"❌ Unexpected error: {e}")