discovery-env / dashboard_routes.py
echoboi
.
591d55e
"""Dashboard FastAPI router β€” mounts the agent monitor dashboard on the HF Space.
Served at:
GET / β†’ dashboard HTML
GET /api/* β†’ dashboard JSON endpoints
The existing Discovery Environment API (/session/*, /health, /problems) is unaffected.
Log location inside the Docker container is /app/logs/, controlled via the
LOGS_BASE_DIR env var that dashboard.py reads.
"""
import os
# Tell dashboard.py where to find logs inside the container.
# Must be set BEFORE importing dashboard so LOG_DIRS is built correctly.
os.environ.setdefault("LOGS_BASE_DIR", "/app/logs")
# dashboard.py is copied into discovery_env_server/ by push_to_hf.sh
from dashboard import ( # noqa: E402
DASHBOARD_HTML,
LOG_DIRS,
discover_agents,
resolve_env_log,
resolve_cmd_log,
resolve_evolve_log,
read_log_lines,
read_phases,
read_doc,
parse_claude_usage,
)
from fastapi import APIRouter
from fastapi.responses import HTMLResponse, JSONResponse
router = APIRouter()
# HF public view β€” strip the LEAKAGE badge (tag only, data/results unchanged)
_HF_HTML = DASHBOARD_HTML.replace(
'const badgeHtml = isLeakage ? `<span class="mc-leakage">⚠ LEAKAGE</span>` : \'\';',
'const badgeHtml = \'\';'
)
@router.get("/", response_class=HTMLResponse, include_in_schema=False)
def dashboard_home():
return _HF_HTML
@router.get("/api/state")
def api_state():
return {proj: discover_agents(proj) for proj in LOG_DIRS}
@router.get("/api/log")
def api_log(project: str, agent: str, offset: int = 0):
fpath = resolve_env_log(project, agent)
lines, done = read_log_lines(fpath, offset, agent_id=agent)
return {"lines": lines, "done": done}
@router.get("/api/cmd-log")
def api_cmd_log(project: str, agent: str, offset: int = 0):
fpath = resolve_cmd_log(project, agent)
lines, _ = read_log_lines(fpath, offset)
return {"lines": lines}
@router.get("/api/evolve-log")
def api_evolve_log(run: str, offset: int = 0):
fpath = resolve_evolve_log(run)
lines, done = read_log_lines(fpath, offset, agent_id=run)
return {"lines": lines, "done": done}
@router.get("/api/claude-usage")
def api_claude_usage(project: str, agent: str):
return parse_claude_usage(project, agent)
@router.get("/api/phases")
def api_phases(project: str, agent: str):
return read_phases(project, agent)
@router.get("/api/plan")
def api_plan(project: str, agent: str):
return {"content": read_doc(project, agent, "PLAN.md")}
@router.get("/api/memories")
def api_memories(project: str, agent: str):
return {
"memoryI": read_doc(project, agent, "memoryI_small_tests.md"),
"memoryII": read_doc(project, agent, "memoryII_rules_tested.md"),
}