|
4 | 4 | import uuid |
5 | 5 | from contextlib import asynccontextmanager |
6 | 6 | from os import getenv |
| 7 | +from pathlib import Path |
7 | 8 |
|
8 | 9 | from fastapi import FastAPI, HTTPException |
9 | | -from fastapi.responses import StreamingResponse |
| 10 | +from fastapi.responses import FileResponse, HTMLResponse, StreamingResponse |
10 | 11 | from websearch_agent.agent import get_workflow_closure |
11 | 12 | from websearch_agent.workflow import ToolCallEvent, InputEvent |
12 | 13 | from pydantic import BaseModel, Field |
@@ -450,6 +451,30 @@ async def health(): |
450 | 451 | return {"status": "healthy", "agent_initialized": get_agent is not None} |
451 | 452 |
|
452 | 453 |
|
| 454 | +# ── Playground UI ──────────────────────────────────────────────────────────── |
| 455 | +_BASE_DIR = Path(__file__).resolve().parent |
| 456 | +_PLAYGROUND_HTML = _BASE_DIR / "playground" / "templates" / "index.html" |
| 457 | +# In Docker the images are copied to /app/images; locally they live at the repo root |
| 458 | +_IMAGES_DIR = _BASE_DIR / "images" |
| 459 | +if not _IMAGES_DIR.is_dir(): |
| 460 | + _IMAGES_DIR = _BASE_DIR.parent.parent.parent / "images" |
| 461 | + |
| 462 | + |
| 463 | +@app.get("/", response_class=HTMLResponse, include_in_schema=False) |
| 464 | +async def playground(): |
| 465 | + """Serve the playground chat UI.""" |
| 466 | + return FileResponse(_PLAYGROUND_HTML) |
| 467 | + |
| 468 | + |
| 469 | +@app.get("/images/{filename:path}", include_in_schema=False) |
| 470 | +async def serve_image(filename: str): |
| 471 | + """Serve images from the project-level images directory.""" |
| 472 | + file_path = _IMAGES_DIR / filename |
| 473 | + if not file_path.is_file(): |
| 474 | + raise HTTPException(status_code=404, detail="Image not found") |
| 475 | + return FileResponse(file_path) |
| 476 | + |
| 477 | + |
453 | 478 | if __name__ == "__main__": |
454 | 479 | import uvicorn |
455 | 480 |
|
|
0 commit comments