Initial commit
This commit is contained in:
206
main.py
Normal file
206
main.py
Normal file
@@ -0,0 +1,206 @@
|
||||
"""
|
||||
LogiFlow AI - Autonomous Logistics Agent System
|
||||
=================================================
|
||||
|
||||
Usage:
|
||||
python main.py --production # Start all agents (production mode)
|
||||
python main.py --dashboard # Launch admin dashboard
|
||||
python main.py --portal # Launch customer portal
|
||||
python main.py --help # Show this help
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import sys
|
||||
import signal
|
||||
from datetime import datetime
|
||||
from typing import Dict, Any
|
||||
|
||||
# Force UTF-8 on Windows so emoji in output doesn't crash
|
||||
if hasattr(sys.stdout, "reconfigure"):
|
||||
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
||||
if hasattr(sys.stderr, "reconfigure"):
|
||||
sys.stderr.reconfigure(encoding="utf-8", errors="replace")
|
||||
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv() # must happen before any config import reads os.getenv()
|
||||
|
||||
from core.logger import logger
|
||||
from core.agent import MasterAgent, Agent
|
||||
from core.message_bus import message_bus
|
||||
from core.http_client import close_session
|
||||
from core.types import AgentTask, MessageType, Priority
|
||||
|
||||
from agents.order_agent import OrderAgent
|
||||
from agents.dispatch_agent import DispatchAgent
|
||||
from agents.fleet_agent import FleetAgent
|
||||
from agents.hub_agent import HubAgent
|
||||
from agents.customer_agent import CustomerAgent
|
||||
from agents.exception_agent import ExceptionAgent
|
||||
from agents.route_optimizer_agent import RouteOptimizerAgent
|
||||
|
||||
|
||||
class LogiFlowAI:
|
||||
"""Main orchestration class — manages all agents and system lifecycle."""
|
||||
|
||||
def __init__(self):
|
||||
logger.info("=" * 60)
|
||||
logger.info("LOGIFLOW AI - AUTONOMOUS LOGISTICS SYSTEM")
|
||||
logger.info("=" * 60)
|
||||
|
||||
self.master_agent = MasterAgent()
|
||||
self.agents: Dict[str, Agent] = {}
|
||||
self.running = False
|
||||
|
||||
def initialize_agents(self):
|
||||
logger.info("Initializing AI Agents...")
|
||||
|
||||
self.agents["ORDER_AGENT"] = OrderAgent()
|
||||
self.agents["DISPATCH_AGENT"] = DispatchAgent()
|
||||
self.agents["FLEET_AGENT"] = FleetAgent()
|
||||
self.agents["HUB_AGENT"] = HubAgent()
|
||||
self.agents["CUSTOMER_AGENT"] = CustomerAgent()
|
||||
self.agents["EXCEPTION_AGENT"] = ExceptionAgent()
|
||||
self.agents["ROUTE_OPTIMIZER"] = RouteOptimizerAgent()
|
||||
|
||||
for agent in self.agents.values():
|
||||
self.master_agent.register_sub_agent(agent)
|
||||
|
||||
logger.info(f"{len(self.agents) + 1} agents initialized (JARVIS + {len(self.agents)} specialized)")
|
||||
|
||||
async def start_agents(self):
|
||||
logger.info("Starting Agent System...")
|
||||
self.running = True
|
||||
|
||||
tasks = [asyncio.create_task(self.master_agent.start())]
|
||||
tasks += [asyncio.create_task(a.start()) for a in self.agents.values()]
|
||||
|
||||
logger.info("All agents running — waiting for work")
|
||||
|
||||
try:
|
||||
await asyncio.gather(*tasks, return_exceptions=True)
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
finally:
|
||||
self.running = False
|
||||
|
||||
async def stop(self):
|
||||
self.running = False
|
||||
await self.master_agent.stop()
|
||||
for agent in self.agents.values():
|
||||
await agent.stop()
|
||||
|
||||
def get_system_status(self) -> Dict[str, Any]:
|
||||
status = {
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"system": "operational" if self.running else "stopped",
|
||||
"agents": {},
|
||||
}
|
||||
for agent_id, agent in self.agents.items():
|
||||
status["agents"][agent_id] = {
|
||||
"status": agent.state.status,
|
||||
"tasks_completed": agent.state.tasks_completed,
|
||||
"current_task": agent.state.current_task,
|
||||
}
|
||||
status["agents"]["JARVIS"] = {
|
||||
"status": self.master_agent.state.status,
|
||||
"sub_agents": len(self.agents),
|
||||
}
|
||||
return status
|
||||
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Run modes #
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
async def production_mode():
|
||||
logger.info("PRODUCTION MODE — connecting to infrastructure")
|
||||
|
||||
try:
|
||||
await message_bus.connect()
|
||||
except Exception as e:
|
||||
logger.warning(f"Could not connect to NATS: {e} — using local in-process fallback")
|
||||
|
||||
system = LogiFlowAI()
|
||||
system.initialize_agents()
|
||||
|
||||
logger.info("Infrastructure connected. Press Ctrl+C to stop.")
|
||||
|
||||
loop = asyncio.get_running_loop()
|
||||
|
||||
def _shutdown(signum, frame):
|
||||
logger.info("Shutdown signal received — stopping agents...")
|
||||
loop.create_task(_graceful_shutdown(system))
|
||||
|
||||
signal.signal(signal.SIGINT, _shutdown)
|
||||
signal.signal(signal.SIGTERM, _shutdown)
|
||||
|
||||
try:
|
||||
await system.start_agents()
|
||||
finally:
|
||||
await message_bus.disconnect()
|
||||
await close_session()
|
||||
logger.info("Clean shutdown complete")
|
||||
|
||||
|
||||
async def _graceful_shutdown(system: LogiFlowAI):
|
||||
await system.stop()
|
||||
tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]
|
||||
for t in tasks:
|
||||
t.cancel()
|
||||
|
||||
|
||||
async def dashboard_mode():
|
||||
import subprocess
|
||||
logger.info("Launching Admin Dashboard at http://localhost:8501")
|
||||
subprocess.run(["streamlit", "run", "dashboard/admin_dashboard.py"])
|
||||
|
||||
|
||||
async def portal_mode():
|
||||
import subprocess
|
||||
logger.info("Launching Customer Portal at http://localhost:8502")
|
||||
subprocess.run(["streamlit", "run", "customer_portal/portal.py", "--server.port", "8502"])
|
||||
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Entry point #
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2 or sys.argv[1] == "--help":
|
||||
print_help()
|
||||
return
|
||||
|
||||
cmd = sys.argv[1]
|
||||
if cmd == "--production":
|
||||
asyncio.run(production_mode())
|
||||
elif cmd == "--dashboard":
|
||||
asyncio.run(dashboard_mode())
|
||||
elif cmd == "--portal":
|
||||
asyncio.run(portal_mode())
|
||||
else:
|
||||
logger.error(f"Unknown argument: {cmd}")
|
||||
print_help()
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def print_help():
|
||||
print("""
|
||||
LogiFlow AI - Autonomous Logistics Agent System
|
||||
===============================================
|
||||
|
||||
Usage:
|
||||
python main.py --production Connect to NATS/Redis/Postgres and run forever
|
||||
python main.py --dashboard Launch Streamlit admin dashboard
|
||||
python main.py --portal Launch Streamlit customer portal
|
||||
python main.py --help Show this help
|
||||
|
||||
Infrastructure (set in .env):
|
||||
NATS nats://doormile@66.116.226.161:4223
|
||||
Redis 66.116.226.255:6380
|
||||
PG DB_HOST / DB_PORT / DB_NAME / DB_USER / DB_PASSWORD
|
||||
API GO_API_BASE_URL
|
||||
""")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user