from fastapi.responses import HTMLResponse, FileResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
from fastapi import FastAPI, Request
from chainlit.utils import mount_chainlit
from pathlib import Path
import os
ROOT_PATH = os.getenv("API_ROOT_PATH", "./")
app = FastAPI(title="AgentTide", description="Precision-Driven Software Engineering Agent")
# Mount static files directory for assets (logo, CSS, JS, etc.)
app.mount("/static", StaticFiles(directory=F"{ROOT_PATH}/public"), name="static")
templates = Jinja2Templates(directory=F"{ROOT_PATH}/static")
@app.get("/", response_class=HTMLResponse)
async def root(request: Request):
"""Serve the AgentTide landing page"""
demo_base_url = os.getenv("DEMO_BASE_URL", "")
return RedirectResponse(url=f"{demo_base_url}/landing_page")
@app.get("/landing_page", response_class=HTMLResponse)
async def landing_page(request: Request):
"""Serve the AgentTide landing page"""
demo_base_url = os.getenv("DEMO_BASE_URL", "")
return templates.TemplateResponse(
"landing_page.html",
{"request": request, "DEMO_BASE_URL": demo_base_url}
)
@app.get("/health")
async def health_check():
"""Health check endpoint"""
return {"status": "healthy", "service": "AgentTide"}
@app.get("/favicon.ico", include_in_schema=False)
async def favicon():
"""Serve favicon"""
favicon_path = Path(F"{ROOT_PATH}/public/favicon.ico")
if favicon_path.exists():
return FileResponse(favicon_path)
else:
# Return 204 No Content if favicon doesn't exist
return HTMLResponse(status_code=204)
@app.get("/logo_dark.png", include_in_schema=False)
async def logo_dark():
"""Serve favicon"""
favicon_path = Path(F"{ROOT_PATH}/public/logo_dark.png")
if favicon_path.exists():
return FileResponse(favicon_path)
else:
# Return 204 No Content if favicon doesn't exist
return HTMLResponse(status_code=204)
@app.get("/codetide-banner.png", include_in_schema=False)
async def codetide_banner():
"""Serve favicon"""
favicon_path = Path(F"{ROOT_PATH}/public/codetide-banner.png")
if favicon_path.exists():
return FileResponse(favicon_path)
else:
# Return 204 No Content if favicon doesn't exist
return HTMLResponse(status_code=204)
@app.get("/agent-tide-demo.gif", include_in_schema=False)
async def agent_tide_deo_gif():
"""Serve favicon"""
favicon_path = Path(F"{ROOT_PATH}/public/agent-tide-demo.gif")
if favicon_path.exists():
return FileResponse(favicon_path)
else:
# Return 204 No Content if favicon doesn't exist
return HTMLResponse(status_code=204)
mount_chainlit(app=app, target=F"{ROOT_PATH}/app.py", path="/tide")
if __name__ == "__main__":
from dotenv import load_dotenv
import uvicorn
load_dotenv()
uvicorn.run(app, host="0.0.0.0", port=7860)