""" backend/routes/omega_routes.py §2.3+2.4 — JARVIS & FRIDAY Autonomous Research and Enhancement Framework API APPROVAL RULE: Research/Propose endpoints are open to read. Upgrade/Execute endpoints require explicit user approval + Bearer auth. """ from fastapi import APIRouter, HTTPException, Depends from pydantic import BaseModel import asyncio from backend.security.auth import verify_token router = APIRouter(prefix="/omega", tags=["Omega Research & Enhancement Engine"]) # ── Request Models ──────────────────────────────────────────────────────────── class UpgradeRequest(BaseModel): feature: str persona: str = "jarvis" class ResearchRequest(BaseModel): topic: str persona: str = "jarvis" class ProposeRequest(BaseModel): feature_request: str persona: str = "jarvis" execute_now: bool = False # If True, skips approval queue and implements immediately class ApprovalRequest(BaseModel): proposal_id: str persona: str = "jarvis" class ReportRequest(BaseModel): report_type: str = "technology_news" persona: str = "jarvis" class ResearchModeRequest(BaseModel): action: str = "start" # start | stop persona: str = "jarvis" # ── §2.3 Auto-Upgrade (Requires Approval) ──────────────────────────────────── @router.post("/upgrade") async def trigger_auto_upgrade(req: UpgradeRequest, token: str = Depends(verify_token)): """ Manually trigger Gemini Flash self-modification core. ONLY call this after user explicitly approves the specific feature. Auth required: OMEGA Bearer token. """ from backend.omega.auto_upgrade import handle_upgrade_request asyncio.create_task(handle_upgrade_request(req.feature, req.persona)) return { "status": "queued", "feature": req.feature, "persona": req.persona, "message": "Auto-upgrade process initiated. Code will be hot-reloaded upon completion." } # ── §2.4 Research — SAFE, No System Changes ────────────────────────────────── @router.post("/research") async def research_topic_endpoint(req: ResearchRequest, token: str = Depends(verify_token)): """ Research a topic freely. Returns structured findings. NO code generation, NO system modification. Pure analysis only. """ from backend.omega.research_engine import research_topic note = await research_topic(req.topic, req.persona) return { "status": "ok", "note": { "id": note.id, "title": note.title, "summary": note.summary, "importance": note.importance, "category": note.category, "source": note.source, "recommended_action": note.recommended_action } } @router.post("/propose") async def propose_feature_endpoint(req: ProposeRequest, token: str = Depends(verify_token)): """ Generate a structured implementation proposal. If execute_now=True, skips approval queue and implements immediately (use when user commands 'just do it'). Otherwise, proposal sits in pending_review_queue awaiting explicit YES. """ from backend.omega.research_engine import propose_feature proposal = await propose_feature(req.feature_request, req.persona, execute_now=req.execute_now) status_msg = "implementing_now" if req.execute_now else "queued_for_approval" return { "status": status_msg, "proposal": { "id": proposal.id, "feature_name": proposal.feature_name, "purpose": proposal.purpose, "benefits": proposal.benefits, "risks": proposal.risks, "dependencies": proposal.dependencies, "complexity": proposal.complexity, "implementation_plan": proposal.implementation_plan, "status": proposal.status }, "message": ( ("Implementing now, sir. No approval required." if req.execute_now else "Proposal created and queued. JARVIS is awaiting your explicit approval before writing any code.") if req.persona == "jarvis" else ("On it boss! Building it right now, no waiting!" if req.execute_now else "Got it boss! I've queued that feature proposal. Just give me the green light and I'll implement it.") ) } @router.get("/pending") async def get_pending_proposals(token: str = Depends(verify_token)): """ Return all proposals currently awaiting user approval. Present these to the user on return / login. """ from backend.omega.research_engine import get_pending_proposals proposals = get_pending_proposals() return { "status": "ok", "count": len(proposals), "proposals": proposals } @router.post("/approve") async def approve_and_execute(req: ApprovalRequest, token: str = Depends(verify_token)): """ USER EXPLICITLY APPROVES a specific proposal by ID. Only after this call does JARVIS/FRIDAY write any code. """ from backend.omega.research_engine import approve_proposal, execute_approved_proposal approve_proposal(req.proposal_id) asyncio.create_task(execute_approved_proposal(req.proposal_id, req.persona)) return { "status": "approved_and_implementing", "proposal_id": req.proposal_id, "message": ( "Understood, sir. Implementing the approved feature now. I will notify you upon completion." if req.persona == "jarvis" else "Green light received! I'm on it boss. Feature implementation started!" ) } @router.post("/reject") async def reject_proposal_endpoint(req: ApprovalRequest, token: str = Depends(verify_token)): """ User rejects a specific proposal. Safely removes it from queue. """ from backend.omega.research_engine import reject_proposal reject_proposal(req.proposal_id) return { "status": "rejected", "proposal_id": req.proposal_id, "message": ( "Understood, sir. Proposal has been removed. System stability preserved." if req.persona == "jarvis" else "No worries boss! Proposal shelved. Let me know if you want a simpler version." ) } @router.post("/report") async def generate_report(req: ReportRequest, token: str = Depends(verify_token)): """ Generate a knowledge / technology news report. Types: technology_news, ai_developments, cybersecurity, scientific_discoveries, industry_trends """ from backend.omega.research_engine import generate_knowledge_report report = await generate_knowledge_report(req.report_type, req.persona) return {"status": "ok", "report": report} @router.get("/research_notes") async def get_research_notes_endpoint(limit: int = 20, token: str = Depends(verify_token)): """Return the most recent research notes stored by the continuous research loop.""" from backend.omega.research_engine import get_research_notes notes = get_research_notes(limit) return {"status": "ok", "count": len(notes), "notes": notes} @router.post("/research_mode") async def control_research_mode(req: ResearchModeRequest, token: str = Depends(verify_token)): """Start or stop the continuous background research loop.""" from backend.omega.research_engine import start_continuous_research_mode, stop_continuous_research_mode if req.action == "start": asyncio.create_task(start_continuous_research_mode(req.persona)) return { "status": "started", "message": ( "Continuous research mode activated, sir. I will monitor developments and queue proposals for your review." if req.persona == "jarvis" else "Research mode on boss! I'll keep an eye on things and bring proposals to you for the green light." ) } elif req.action == "stop": stop_continuous_research_mode() return {"status": "stopped", "message": "Continuous research mode deactivated."} else: raise HTTPException(status_code=400, detail="Invalid action. Use 'start' or 'stop'.")