import sys import os sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import json import uuid import shutil import time import re from fastapi import FastAPI, UploadFile, File from fastapi.responses import HTMLResponse from pydantic import BaseModel from sqlalchemy import text from src.core.engine import ModelEngine from src.core.memory import MemoryManager from src.core.saas_api import SaasAPI from src.core.integrations import IntegrationManager from src.agents.manager import ManagerAgent from src.agents.coder import CoderAgent from src.agents.vision import VisionAgent try: if 'engine' not in globals(): engine = ModelEngine() except: engine = None memory = MemoryManager() saas = SaasAPI() integrations = IntegrationManager(memory) manager = ManagerAgent(engine, memory) coder = CoderAgent(engine, memory) vision = VisionAgent() app = FastAPI() class ChatRequest(BaseModel): user_id: int store_id: int message: str class FeedbackRequest(BaseModel): prompt: str response: str feedback: str correction: str = "" def clean_output(text): text = re.sub(r".*?", "", text, flags=re.DOTALL) return text.replace("", "").replace("", "").strip() # --- HTML UI (Minified) --- html_content = """ Project A
Project A
Project A đang suy nghĩ...
""" @app.get("/", response_class=HTMLResponse) async def root(): return html_content @app.post("/upload") async def upload_file(file: UploadFile = File(...)): file_ext = file.filename.split(".")[-1].lower() filename = f"{uuid.uuid4()}.{file_ext}" save_path = f"src/data/{filename}" os.makedirs("src/data", exist_ok=True) with open(save_path, "wb") as buffer: shutil.copyfileobj(file.file, buffer) analysis = f"File {file.filename}" if file_ext in ['jpg', 'png', 'jpeg', 'webp']: analysis = vision.analyze_media(save_path) memory.save_attachment(1, 1, file.filename, file_ext, analysis) return {"status": "success", "vision_analysis": analysis} @app.post("/feedback") async def save_feedback(req: FeedbackRequest): # --- SAVE TO NEON DB --- try: with memory.get_conn() as conn: conn.execute(text(""" INSERT INTO feedback_logs (user_id, prompt, ai_response, user_correction, feedback_type) VALUES (:uid, :p, :r, :c, :f) """), { "uid": 1, "p": req.prompt, "r": req.response, "c": req.correction, "f": req.feedback }) conn.commit() return {"status": "recorded_in_db"} except Exception as e: print(f"Feedback Error: {e}") return {"status": "error", "message": str(e)} @app.post("/chat") async def chat_endpoint(req: ChatRequest): memory.add_message(req.user_id, req.store_id, "user", req.message) history = memory.get_context_string(req.user_id) decision = manager.analyze_task(req.message, history) cat = decision.get("category", "GENERAL") if "ảnh" in req.message.lower() or "hình" in req.message.lower(): cat = "GENERAL" resp = "" if cat == "TECHNICAL": plan = manager.plan(req.message, history) code = coder.write_code(req.message, plan) match = re.search(r"```json\n(.*?)\n```", code, re.DOTALL) if match: integrations.deploy_internal(req.store_id, match.group(1)) resp = f"Đã thiết kế quy trình:\n{code}" elif cat == "DATA_INTERNAL": data = saas.get_sales_report(req.store_id) resp = manager.consult(req.message, str(data), history) else: resp = manager.consult(req.message, "", history) final = clean_output(resp) memory.add_message(req.user_id, req.store_id, "assistant", final) return {"response": final}