Mohammad Wasil
commited on
Commit
·
1b8636f
1
Parent(s):
468ab63
Fix frontend connection: use relative API path
Browse files- frontend/js/app.js +0 -48
- main.py +30 -11
frontend/js/app.js
CHANGED
|
@@ -198,52 +198,6 @@ function escapeHtml(unsafe) {
|
|
| 198 |
.replace(/'/g, "'");
|
| 199 |
}
|
| 200 |
|
| 201 |
-
// function renderContent(content) {
|
| 202 |
-
// // sanitize, then convert simple markdown + lists + newlines to HTML
|
| 203 |
-
// let html = escapeHtml(content);
|
| 204 |
-
|
| 205 |
-
// // bold **text**
|
| 206 |
-
// html = html.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>");
|
| 207 |
-
|
| 208 |
-
// // split into lines and convert to paragraphs / lists
|
| 209 |
-
// const lines = html.split(/\r?\n/);
|
| 210 |
-
// let out = "";
|
| 211 |
-
// let inUl = false;
|
| 212 |
-
// let inOl = false;
|
| 213 |
-
|
| 214 |
-
// for (let rawLine of lines) {
|
| 215 |
-
// const line = rawLine.trim();
|
| 216 |
-
// if (line === "") {
|
| 217 |
-
// // blank line -> close lists and add spacing
|
| 218 |
-
// if (inUl) { out += "</ul>"; inUl = false; }
|
| 219 |
-
// if (inOl) { out += "</ol>"; inOl = false; }
|
| 220 |
-
// out += "<p></p>";
|
| 221 |
-
// continue;
|
| 222 |
-
// }
|
| 223 |
-
|
| 224 |
-
// if (/^[-•]\s+/.test(line)) {
|
| 225 |
-
// if (!inUl) { if (inOl) { out += "</ol>"; inOl = false; } out += "<ul>"; inUl = true; }
|
| 226 |
-
// out += `<li>${line.replace(/^[-•]\s+/, "")}</li>`;
|
| 227 |
-
// continue;
|
| 228 |
-
// }
|
| 229 |
-
|
| 230 |
-
// if (/^\d+\.\s+/.test(line)) {
|
| 231 |
-
// if (!inOl) { if (inUl) { out += "</ul>"; inUl = false; } out += "<ol>"; inOl = true; }
|
| 232 |
-
// out += `<li>${line.replace(/^\d+\.\s+/, "")}</li>`;
|
| 233 |
-
// continue;
|
| 234 |
-
// }
|
| 235 |
-
|
| 236 |
-
// // normal paragraph line
|
| 237 |
-
// if (inUl) { out += "</ul>"; inUl = false; }
|
| 238 |
-
// if (inOl) { out += "</ol>"; inOl = false; }
|
| 239 |
-
// out += `<p>${line}</p>`;
|
| 240 |
-
// }
|
| 241 |
-
|
| 242 |
-
// if (inUl) out += "</ul>";
|
| 243 |
-
// if (inOl) out += "</ol>";
|
| 244 |
-
// return out;
|
| 245 |
-
// }
|
| 246 |
-
|
| 247 |
function renderContent(content) {
|
| 248 |
let html = escapeHtml(content);
|
| 249 |
html = html.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>");
|
|
@@ -286,8 +240,6 @@ function renderContent(content) {
|
|
| 286 |
}
|
| 287 |
|
| 288 |
|
| 289 |
-
|
| 290 |
-
|
| 291 |
function addMessageToUI(content, sender, sources = null) {
|
| 292 |
const messageDiv = document.createElement('div');
|
| 293 |
messageDiv.className = `message ${sender}`;
|
|
|
|
| 198 |
.replace(/'/g, "'");
|
| 199 |
}
|
| 200 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 201 |
function renderContent(content) {
|
| 202 |
let html = escapeHtml(content);
|
| 203 |
html = html.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>");
|
|
|
|
| 240 |
}
|
| 241 |
|
| 242 |
|
|
|
|
|
|
|
| 243 |
function addMessageToUI(content, sender, sources = null) {
|
| 244 |
const messageDiv = document.createElement('div');
|
| 245 |
messageDiv.className = `message ${sender}`;
|
main.py
CHANGED
|
@@ -11,12 +11,18 @@ from agent import SupportAgent
|
|
| 11 |
|
| 12 |
# Loguru Setup
|
| 13 |
logger.remove()
|
| 14 |
-
logger.add(sys.stdout, format="<green>{time}</green> | <level>{
|
| 15 |
|
| 16 |
@asynccontextmanager
|
| 17 |
async def lifespan(app: FastAPI):
|
| 18 |
logger.info("Initializing SmartCoffee Agent for Hugging Face...")
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
yield
|
| 21 |
logger.info("Shutting down...")
|
| 22 |
|
|
@@ -30,14 +36,27 @@ app.add_middleware(
|
|
| 30 |
allow_headers=["*"],
|
| 31 |
)
|
| 32 |
|
| 33 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
@app.post("/api/v1/chat", response_model=ChatResponse)
|
| 35 |
async def chat(request: ChatRequest):
|
| 36 |
if request.session_id == "default":
|
| 37 |
request.session_id = f"hf_{uuid.uuid4().hex[:12]}"
|
| 38 |
|
|
|
|
|
|
|
|
|
|
| 39 |
try:
|
| 40 |
-
#
|
| 41 |
result = app.state.agent.run(request.question, session_id=request.session_id)
|
| 42 |
|
| 43 |
return ChatResponse(
|
|
@@ -47,13 +66,13 @@ async def chat(request: ChatRequest):
|
|
| 47 |
timestamp=result.get("timestamp", time.time())
|
| 48 |
)
|
| 49 |
except Exception as e:
|
| 50 |
-
logger.error(f"Chat Error: {e}")
|
| 51 |
-
raise HTTPException(status_code=500, detail=
|
| 52 |
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
|
|
|
| 56 |
|
| 57 |
-
#
|
| 58 |
-
# This must be at the BOTTOM so it doesn't override /api/ routes
|
| 59 |
app.mount("/", StaticFiles(directory="frontend", html=True), name="static")
|
|
|
|
| 11 |
|
| 12 |
# Loguru Setup
|
| 13 |
logger.remove()
|
| 14 |
+
logger.add(sys.stdout, format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level}</level> | {message}", level="INFO")
|
| 15 |
|
| 16 |
@asynccontextmanager
|
| 17 |
async def lifespan(app: FastAPI):
|
| 18 |
logger.info("Initializing SmartCoffee Agent for Hugging Face...")
|
| 19 |
+
try:
|
| 20 |
+
# Initialize agent once and store in app state
|
| 21 |
+
app.state.agent = SupportAgent()
|
| 22 |
+
logger.success("SupportAgent successfully initialized.")
|
| 23 |
+
except Exception as e:
|
| 24 |
+
logger.error(f"Critical Startup Error: {e}")
|
| 25 |
+
# We don't raise here to allow the container to stay up so you can see logs
|
| 26 |
yield
|
| 27 |
logger.info("Shutting down...")
|
| 28 |
|
|
|
|
| 36 |
allow_headers=["*"],
|
| 37 |
)
|
| 38 |
|
| 39 |
+
# 1. ADDED: Health Check Route (Fixes the 404 error)
|
| 40 |
+
@app.get("/health")
|
| 41 |
+
async def health():
|
| 42 |
+
return {"status": "healthy", "time": time.time(), "agent_loaded": hasattr(app.state, 'agent')}
|
| 43 |
+
|
| 44 |
+
# 2. Metrics Route
|
| 45 |
+
@app.get("/metrics")
|
| 46 |
+
def metrics():
|
| 47 |
+
return Response(generate_latest(), media_type=CONTENT_TYPE_LATEST)
|
| 48 |
+
|
| 49 |
+
# 3. Core Chat API (Check that frontend sends 'question' and 'session_id')
|
| 50 |
@app.post("/api/v1/chat", response_model=ChatResponse)
|
| 51 |
async def chat(request: ChatRequest):
|
| 52 |
if request.session_id == "default":
|
| 53 |
request.session_id = f"hf_{uuid.uuid4().hex[:12]}"
|
| 54 |
|
| 55 |
+
if not hasattr(app.state, 'agent'):
|
| 56 |
+
raise HTTPException(status_code=503, detail="Agent logic is still initializing or failed to load.")
|
| 57 |
+
|
| 58 |
try:
|
| 59 |
+
# Calls the .run() method you shared in your agent.py
|
| 60 |
result = app.state.agent.run(request.question, session_id=request.session_id)
|
| 61 |
|
| 62 |
return ChatResponse(
|
|
|
|
| 66 |
timestamp=result.get("timestamp", time.time())
|
| 67 |
)
|
| 68 |
except Exception as e:
|
| 69 |
+
logger.error(f"Chat Execution Error: {e}")
|
| 70 |
+
raise HTTPException(status_code=500, detail=str(e))
|
| 71 |
|
| 72 |
+
# 4. Sync Route (Add if your JS CONFIG.API_ENDPOINT still uses /chat/sync)
|
| 73 |
+
@app.post("/api/v1/chat/sync", response_model=ChatResponse)
|
| 74 |
+
async def chat_sync(request: ChatRequest):
|
| 75 |
+
return await chat(request)
|
| 76 |
|
| 77 |
+
# 5. Static Files (MOUNTED LAST to prevent route hijacking)
|
|
|
|
| 78 |
app.mount("/", StaticFiles(directory="frontend", html=True), name="static")
|