Spaces:
Running
Running
File size: 3,735 Bytes
c216959 0491e54 c216959 0491e54 7cf341b 0491e54 ac59ee6 02679c3 ac59ee6 02679c3 ac59ee6 02679c3 ac59ee6 02679c3 ac59ee6 02679c3 ac59ee6 0491e54 c216959 0491e54 02679c3 361a507 02679c3 361a507 02679c3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
"""
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}")
|