ZKnowledgeAgent / app /main.py
mghfuran's picture
improved UI
6655bba
Raw
History Blame Contribute Delete
5.94 kB
import uvicorn
from fastapi import FastAPI, Form
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from app.services.llm_service import ask_llm
app = FastAPI()
# Mount the static directory to serve local image assets securely
app.mount("/static", StaticFiles(directory="app/static"), name="static")
CHAT_HTML = """
<html>
<head>
<title>Virtual Agent</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f0f2f5;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.chat-container {
width: 520px;
background: white;
padding: 30px;
border-radius: 16px;
box-shadow: 0px 10px 30px rgba(0, 0, 0, 0.08);
display: flex;
flex-direction: column;
}
.brand-header {
display: flex;
align-items: center;
gap: 15px;
margin-bottom: 5px;
}
.logo-img {
width: 50px;
height: 50px;
object-fit: contain;
border-radius: 50%;
}
.brand-title {
font-size: 24px;
font-weight: 700;
color: #1e293b;
margin: 0;
}
.brand-description {
font-size: 13px;
color: #64748b;
margin: 0 0 20px 0;
line-height: 1.5;
border-bottom: 1px solid #e2e8f0;
padding-bottom: 15px;
}
.messages {
height: 330px;
overflow-y: auto;
border: 1px solid #e2e8f0;
border-radius: 10px;
padding: 15px;
margin-bottom: 15px;
background-color: #fafafa;
}
.message-row {
margin-bottom: 12px;
line-height: 1.5;
font-size: 14px;
}
.user {
color: #1d4ed8;
}
.bot {
color: #047857;
background-color: #f0fdf4;
padding: 8px 12px;
border-radius: 8px;
border-left: 3px solid #10b981;
}
.input-group {
display: flex;
gap: 10px;
margin-bottom: 15px;
}
input {
flex: 1;
padding: 12px;
border: 1px solid #cbd5e1;
border-radius: 8px;
font-size: 14px;
outline: none;
transition: border-color 0.2s;
}
input:focus {
border-color: #3b82f6;
}
button {
padding: 12px 24px;
background-color: #2563eb;
color: white;
border: none;
border-radius: 8px;
font-weight: 600;
cursor: pointer;
transition: background-color 0.2s;
}
button:hover {
background-color: #1d4ed8;
}
.chat-footer {
text-align: center;
font-size: 11px;
color: #94a3b8;
margin-top: 5px;
letter-spacing: 0.3px;
}
.chat-footer a {
color: #64748b;
text-decoration: none;
font-weight: 500;
}
.chat-footer a:hover {
text-decoration: underline;
color: #2563eb;
}
</style>
</head>
<body>
<div class="chat-container">
<div class="brand-header">
<img class="logo-img" src="/static/Z_Logo_Circle.png" alt="Z Virtual Agent Logo">
<h2 class="brand-title">Virtual Agent</h2>
</div>
<p class="brand-description">
Intelligent automation and knowledge retrieval framework for Z Logistics operations. Ask questions regarding company SOPs, driver policies, onboarding protocols, and compliance directives.
</p>
<div class="messages" id="messages"></div>
<div class="input-group">
<input type="text" id="messageInput" placeholder="Ask Z Virtual Agent...">
<button onclick="sendMessage()">Send</button>
</div>
<div class="chat-footer">
Powered by <b>Z Consulting</b> &bull; <a href="https://www.zedtex.us" target="_blank">www.zedtex.us</a>
</div>
</div>
<script>
async function sendMessage() {
let input = document.getElementById("messageInput");
let message = input.value;
if(message.trim() === "") return;
let messages = document.getElementById("messages");
messages.innerHTML += `
<div class="message-row user">
<b>You:</b> ${message}
</div>
`;
messages.scrollTop = messages.scrollHeight;
input.value = "";
let response = await fetch('/api/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: `message=${encodeURIComponent(message)}`
});
let data = await response.json();
messages.innerHTML += `
<div class="message-row bot">
<b>Z:</b> ${data.response}
</div>
`;
messages.scrollTop = messages.scrollHeight;
}
document.getElementById("messageInput")
.addEventListener("keypress", function(event) {
if (event.key === "Enter") {
event.preventDefault();
sendMessage();
}
});
</script>
</body>
</html>
"""
@app.get("/", response_class=HTMLResponse)
def home():
return CHAT_HTML
@app.get("/chat", response_class=HTMLResponse)
def chat_page():
return CHAT_HTML
@app.post("/api/chat")
def api_chat(message: str = Form(...)):
bot_response = ask_llm(message)
return {
"response": bot_response
}
if __name__ == "__main__":
uvicorn.run("app.main:app", host="0.0.0.0", port=7860, reload=False)