| """
|
| ORYNXML Complete Backend with AI Agents
|
| FastAPI REST API + Manus Agent + SWE Agent + Browser Agent + HuggingFace Agent
|
| """
|
|
|
| from fastapi import FastAPI, HTTPException, BackgroundTasks
|
| from fastapi.middleware.cors import CORSMiddleware
|
| from pydantic import BaseModel
|
| from typing import Optional, List, Dict, Any
|
| import os
|
| import sys
|
| import sqlite3
|
| import hashlib
|
| import asyncio
|
| from datetime import datetime
|
|
|
|
|
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
|
|
|
|
| from app.agent.manus import Manus
|
| from app.agent.swe import SWEAgent
|
| from app.agent.browser import BrowserAgent
|
| from app.agent.data_analysis import DataAnalysis
|
| from app.llm import get_llm
|
| from app.tool.tool_collection import ToolCollection
|
|
|
|
|
| HF_TOKEN = os.getenv("HF_TOKEN", "")
|
|
|
|
|
| CLOUDFLARE_CONFIG = {
|
| "api_token": os.getenv("CLOUDFLARE_API_TOKEN", ""),
|
| "account_id": os.getenv("CLOUDFLARE_ACCOUNT_ID", "62af59a7ac82b29543577ee6800735ee"),
|
| "d1_database_id": os.getenv("CLOUDFLARE_D1_DATABASE_ID", "6d887f74-98ac-4db7-bfed-8061903d1f6c"),
|
| "r2_bucket_name": os.getenv("CLOUDFLARE_R2_BUCKET_NAME", "openmanus-storage"),
|
| "kv_namespace_id": os.getenv("CLOUDFLARE_KV_NAMESPACE_ID", "87f4aa01410d4fb19821f61006f94441"),
|
| "kv_namespace_cache": os.getenv("CLOUDFLARE_KV_CACHE_ID", "7b58c88292c847d1a82c8e0dd5129f37"),
|
| }
|
|
|
|
|
| manus_agent = None
|
| swe_agent = None
|
| browser_agent = None
|
| data_agent = None
|
|
|
|
|
| app = FastAPI(
|
| title="ORYNXML AI Platform with Agents",
|
| description="Complete AI backend with Manus, SWE, Browser, and Data Analysis agents",
|
| version="2.0.0",
|
| )
|
|
|
|
|
| app.add_middleware(
|
| CORSMiddleware,
|
| allow_origins=["*"],
|
| allow_credentials=True,
|
| allow_methods=["*"],
|
| allow_headers=["*"],
|
| )
|
|
|
|
|
| def init_database():
|
| conn = sqlite3.connect("openmanus.db")
|
| cursor = conn.cursor()
|
| cursor.execute("""
|
| CREATE TABLE IF NOT EXISTS users (
|
| id INTEGER PRIMARY KEY AUTOINCREMENT,
|
| mobile TEXT UNIQUE NOT NULL,
|
| name TEXT NOT NULL,
|
| password_hash TEXT NOT NULL,
|
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
| )
|
| """)
|
| conn.commit()
|
| conn.close()
|
|
|
| init_database()
|
|
|
|
|
| class SignupRequest(BaseModel):
|
| mobile: str
|
| name: str
|
| password: str
|
|
|
| class LoginRequest(BaseModel):
|
| mobile: str
|
| password: str
|
|
|
| class AgentRequest(BaseModel):
|
| prompt: str
|
| agent: Optional[str] = "manus"
|
|
|
| class CodeRequest(BaseModel):
|
| task: str
|
| language: Optional[str] = "python"
|
|
|
| class BrowserRequest(BaseModel):
|
| task: str
|
| url: Optional[str] = None
|
|
|
| class DataRequest(BaseModel):
|
| data: Any
|
| task: str
|
|
|
|
|
| def hash_password(password: str) -> str:
|
| return hashlib.sha256(password.encode()).hexdigest()
|
|
|
| def verify_password(password: str, password_hash: str) -> bool:
|
| return hash_password(password) == password_hash
|
|
|
|
|
| @app.on_event("startup")
|
| async def startup_event():
|
| global manus_agent, swe_agent, browser_agent, data_agent
|
|
|
| print("🚀 Initializing AI Agents...")
|
|
|
| try:
|
|
|
| manus_agent = await Manus.create()
|
| print("✅ Manus Agent initialized")
|
|
|
|
|
| swe_agent = await SWEAgent.create()
|
| print("✅ SWE Agent initialized")
|
|
|
|
|
| browser_agent = await BrowserAgent.create()
|
| print("✅ Browser Agent initialized")
|
|
|
|
|
| data_agent = await DataAnalysis.create()
|
| print("✅ Data Analysis Agent initialized")
|
|
|
| print("🎉 All agents ready!")
|
|
|
| except Exception as e:
|
| print(f"⚠️ Warning: Could not initialize all agents: {e}")
|
| print("API will still work with limited functionality")
|
|
|
|
|
|
|
| @app.get("/")
|
| async def root():
|
| return {
|
| "message": "ORYNXML AI Platform with Agents",
|
| "version": "2.0.0",
|
| "agents": {
|
| "manus": "Main agent with all capabilities" if manus_agent else "Not initialized",
|
| "swe": "Software Engineer agent" if swe_agent else "Not initialized",
|
| "browser": "Browser automation agent" if browser_agent else "Not initialized",
|
| "data": "Data analysis agent" if data_agent else "Not initialized",
|
| },
|
| "endpoints": {
|
| "health": "/health",
|
| "auth": "/auth/signup, /auth/login",
|
| "agents": "/agent/run, /agent/code, /agent/browser, /agent/data",
|
| }
|
| }
|
|
|
| @app.get("/health")
|
| async def health_check():
|
| return {
|
| "status": "healthy",
|
| "timestamp": datetime.now().isoformat(),
|
| "agents_initialized": {
|
| "manus": manus_agent is not None,
|
| "swe": swe_agent is not None,
|
| "browser": browser_agent is not None,
|
| "data": data_agent is not None,
|
| },
|
| "cloudflare_configured": bool(CLOUDFLARE_CONFIG["api_token"]),
|
| }
|
|
|
| @app.post("/auth/signup")
|
| async def signup(request: SignupRequest):
|
| try:
|
| if len(request.password) < 6:
|
| raise HTTPException(status_code=400, detail="Password must be at least 6 characters")
|
|
|
| conn = sqlite3.connect("openmanus.db")
|
| cursor = conn.cursor()
|
|
|
| cursor.execute("SELECT mobile FROM users WHERE mobile = ?", (request.mobile,))
|
| if cursor.fetchone():
|
| conn.close()
|
| raise HTTPException(status_code=400, detail="Mobile number already registered")
|
|
|
| password_hash = hash_password(request.password)
|
| cursor.execute(
|
| "INSERT INTO users (mobile, name, password_hash) VALUES (?, ?, ?)",
|
| (request.mobile, request.name, password_hash)
|
| )
|
| conn.commit()
|
| conn.close()
|
|
|
| return {
|
| "success": True,
|
| "message": "Account created successfully",
|
| "mobile": request.mobile,
|
| "name": request.name
|
| }
|
|
|
| except HTTPException:
|
| raise
|
| except Exception as e:
|
| raise HTTPException(status_code=500, detail=f"Registration failed: {str(e)}")
|
|
|
| @app.post("/auth/login")
|
| async def login(request: LoginRequest):
|
| try:
|
| conn = sqlite3.connect("openmanus.db")
|
| cursor = conn.cursor()
|
|
|
| cursor.execute(
|
| "SELECT name, password_hash FROM users WHERE mobile = ?",
|
| (request.mobile,)
|
| )
|
| result = cursor.fetchone()
|
| conn.close()
|
|
|
| if not result:
|
| raise HTTPException(status_code=401, detail="Invalid mobile number or password")
|
|
|
| name, password_hash = result
|
|
|
| if not verify_password(request.password, password_hash):
|
| raise HTTPException(status_code=401, detail="Invalid mobile number or password")
|
|
|
| return {
|
| "success": True,
|
| "message": "Login successful",
|
| "user": {
|
| "mobile": request.mobile,
|
| "name": name
|
| },
|
| "token": f"session_{hash_password(request.mobile + str(datetime.now()))[:32]}"
|
| }
|
|
|
| except HTTPException:
|
| raise
|
| except Exception as e:
|
| raise HTTPException(status_code=500, detail=f"Login failed: {str(e)}")
|
|
|
| @app.post("/agent/run")
|
| async def run_agent(request: AgentRequest):
|
| """Run any agent with a prompt"""
|
| try:
|
| agent_name = request.agent.lower()
|
|
|
|
|
| if agent_name == "manus":
|
| if not manus_agent:
|
| raise HTTPException(status_code=503, detail="Manus agent not initialized")
|
| agent = manus_agent
|
| elif agent_name == "swe":
|
| if not swe_agent:
|
| raise HTTPException(status_code=503, detail="SWE agent not initialized")
|
| agent = swe_agent
|
| elif agent_name == "browser":
|
| if not browser_agent:
|
| raise HTTPException(status_code=503, detail="Browser agent not initialized")
|
| agent = browser_agent
|
| elif agent_name == "data":
|
| if not data_agent:
|
| raise HTTPException(status_code=503, detail="Data agent not initialized")
|
| agent = data_agent
|
| else:
|
| raise HTTPException(status_code=400, detail=f"Unknown agent: {agent_name}")
|
|
|
|
|
| result = await agent.run(request.prompt)
|
|
|
| return {
|
| "success": True,
|
| "agent": agent_name,
|
| "prompt": request.prompt,
|
| "result": str(result),
|
| "timestamp": datetime.now().isoformat()
|
| }
|
|
|
| except HTTPException:
|
| raise
|
| except Exception as e:
|
| raise HTTPException(status_code=500, detail=f"Agent execution failed: {str(e)}")
|
|
|
| @app.post("/agent/code")
|
| async def generate_code(request: CodeRequest):
|
| """Software Engineer Agent - Generate code"""
|
| try:
|
| if not swe_agent:
|
| raise HTTPException(status_code=503, detail="SWE agent not initialized")
|
|
|
| prompt = f"Generate {request.language} code for: {request.task}"
|
| result = await swe_agent.run(prompt)
|
|
|
| return {
|
| "success": True,
|
| "task": request.task,
|
| "language": request.language,
|
| "code": str(result),
|
| "timestamp": datetime.now().isoformat()
|
| }
|
|
|
| except HTTPException:
|
| raise
|
| except Exception as e:
|
| raise HTTPException(status_code=500, detail=f"Code generation failed: {str(e)}")
|
|
|
| @app.post("/agent/browser")
|
| async def browser_automation(request: BrowserRequest):
|
| """Browser Agent - Automate web tasks"""
|
| try:
|
| if not browser_agent:
|
| raise HTTPException(status_code=503, detail="Browser agent not initialized")
|
|
|
| prompt = f"{request.task}"
|
| if request.url:
|
| prompt += f" on {request.url}"
|
|
|
| result = await browser_agent.run(prompt)
|
|
|
| return {
|
| "success": True,
|
| "task": request.task,
|
| "url": request.url,
|
| "result": str(result),
|
| "timestamp": datetime.now().isoformat()
|
| }
|
|
|
| except HTTPException:
|
| raise
|
| except Exception as e:
|
| raise HTTPException(status_code=500, detail=f"Browser automation failed: {str(e)}")
|
|
|
| @app.post("/agent/data")
|
| async def analyze_data(request: DataRequest):
|
| """Data Analysis Agent - Analyze and visualize data"""
|
| try:
|
| if not data_agent:
|
| raise HTTPException(status_code=503, detail="Data agent not initialized")
|
|
|
| prompt = f"Analyze this data: {request.data}. Task: {request.task}"
|
| result = await data_agent.run(prompt)
|
|
|
| return {
|
| "success": True,
|
| "task": request.task,
|
| "result": str(result),
|
| "timestamp": datetime.now().isoformat()
|
| }
|
|
|
| except HTTPException:
|
| raise
|
| except Exception as e:
|
| raise HTTPException(status_code=500, detail=f"Data analysis failed: {str(e)}")
|
|
|
| @app.get("/agents/list")
|
| async def list_agents():
|
| """List all available agents and their status"""
|
| return {
|
| "agents": [
|
| {
|
| "name": "manus",
|
| "description": "Main agent with all capabilities (chat, coding, browsing, data analysis)",
|
| "status": "initialized" if manus_agent else "not initialized",
|
| "endpoint": "/agent/run"
|
| },
|
| {
|
| "name": "swe",
|
| "description": "Software Engineer agent (code generation, debugging, refactoring)",
|
| "status": "initialized" if swe_agent else "not initialized",
|
| "endpoint": "/agent/code"
|
| },
|
| {
|
| "name": "browser",
|
| "description": "Browser automation agent (web scraping, form filling, navigation)",
|
| "status": "initialized" if browser_agent else "not initialized",
|
| "endpoint": "/agent/browser"
|
| },
|
| {
|
| "name": "data",
|
| "description": "Data analysis agent (charts, visualization, statistics)",
|
| "status": "initialized" if data_agent else "not initialized",
|
| "endpoint": "/agent/data"
|
| }
|
| ]
|
| }
|
|
|
| @app.get("/cloudflare/status")
|
| async def cloudflare_status():
|
| services = []
|
| if CLOUDFLARE_CONFIG["api_token"]:
|
| services.append("✅ API Token Configured")
|
| if CLOUDFLARE_CONFIG["d1_database_id"]:
|
| services.append("✅ D1 Database Connected")
|
| if CLOUDFLARE_CONFIG["r2_bucket_name"]:
|
| services.append("✅ R2 Storage Connected")
|
| if CLOUDFLARE_CONFIG["kv_namespace_id"]:
|
| services.append("✅ KV Sessions Connected")
|
| if CLOUDFLARE_CONFIG["kv_namespace_cache"]:
|
| services.append("✅ KV Cache Connected")
|
|
|
| return {
|
| "configured": len(services) > 0,
|
| "services": services,
|
| "account_id": CLOUDFLARE_CONFIG["account_id"]
|
| }
|
|
|
| if __name__ == "__main__":
|
| uvicorn.run(
|
| app,
|
| host="0.0.0.0",
|
| port=7860,
|
| log_level="info"
|
| )
|
|
|