import os from pathlib import Path from fastapi import FastAPI from fastapi.responses import FileResponse from fastapi.staticfiles import StaticFiles from fastapi.middleware.cors import CORSMiddleware from app.core.document_indexer import DocumentIndexer from app.core.data_store import DataStore from app.agent.agent_engine import AgentEngine from app.api import routes_chat, routes_data, routes_proactive app = FastAPI( title="ParcelPilot AI Operating System", description="Production-grade AI Support Agent, Model Context Protocol (MCP) Bridge & Proactive Operations Platform for CalQuity", version="2.0.0" ) # CORS app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Initialize Core Services on startup indexer = DocumentIndexer() data_store = DataStore() agent_engine = AgentEngine(indexer, data_store) # Inject into route modules routes_chat.agent_engine_instance = agent_engine routes_data.data_store_instance = data_store routes_data.indexer_instance = indexer routes_proactive.data_store_instance = data_store # Register API Routers app.include_router(routes_chat.router) app.include_router(routes_data.router) app.include_router(routes_proactive.router) @app.get("/api/health") @app.get("/health") def health_check(): return { "status": "healthy", "system": "ParcelPilot AI Operations Engine", "snapshot_reference": str(data_store.snapshot_datetime), "indexed_documents": len(indexer.documents), "total_accounts": len(data_store.accounts), "total_orders": len(data_store.orders), "total_tickets": len(data_store.tickets), "mcp_enabled": True } @app.get("/api/mcp/tools") def get_mcp_tools(): """ CalQuity Model Context Protocol (MCP) Integration Specification. Exposes ParcelPilot's tools as standard MCP JSON schemas for external AI agent integration. """ return { "mcp_version": "1.0.0", "server_name": "parcelpilot-mcp-server", "description": "ParcelPilot AI Support & Operations Tool Suite for Model Context Protocol integration.", "tools": [ { "name": "document_search", "description": "Searches ParcelPilot policies, customer enterprise agreements, SOPs, and ops guides with source authority ranking.", "parameters": { "type": "object", "properties": { "query": {"type": "string", "description": "Search query terms"}, "account_id": {"type": "string", "description": "Target account ID for privacy scoping"} }, "required": ["query"] } }, { "name": "calculate_cancellation_fee", "description": "Evaluates order cancellation eligibility and fee ($0 for Northstar contract waiver vs INR 250 SOP v4 default).", "parameters": { "type": "object", "properties": { "order_id": {"type": "string", "description": "Order ID (e.g. ORD-1001)"} }, "required": ["order_id"] } }, { "name": "calculate_service_credit", "description": "Calculates failed pickup service credit eligibility (LumenWorks >4h delay rule vs SOP v4 >2h delay rule).", "parameters": { "type": "object", "properties": { "order_id": {"type": "string", "description": "Order ID (e.g. ORD-2002)"} }, "required": ["order_id"] } }, { "name": "execute_action", "description": "Prepares state-changing actions (escalations, ticket updates, credit approvals) requiring human confirmation.", "parameters": { "type": "object", "properties": { "action_name": {"type": "string", "enum": ["escalate_ticket", "update_ticket", "create_followup_task", "approve_service_credit"]}, "parameters": {"type": "object"} }, "required": ["action_name"] } } ] } frontend_dir = Path(__file__).resolve().parent.parent / "frontend" @app.get("/") def serve_index(): index_file = frontend_dir / "index.html" if index_file.exists(): return FileResponse(str(index_file)) return {"message": "ParcelPilot AI Backend Server Running"} if frontend_dir.exists(): app.mount("/", StaticFiles(directory=str(frontend_dir)), name="static_root") if __name__ == "__main__": import uvicorn uvicorn.run("app.main:app", host="0.0.0.0", port=8000, reload=True)