All `except Exception:` now catch as `except Exception as exc:` with appropriate logging (warning for critical paths, debug for graceful degradation). Added logger setup to 4 files that lacked it: - src/timmy/memory/vector_store.py - src/dashboard/middleware/csrf.py - src/dashboard/middleware/security_headers.py - src/spark/memory.py 31 files changed across timmy core, dashboard, infrastructure, integrations. Zero bare excepts remain. 1340 tests passing.
78 lines
2.4 KiB
Python
78 lines
2.4 KiB
Python
"""Experiment dashboard routes — autoresearch experiment monitoring.
|
|
|
|
Provides endpoints for viewing, starting, and monitoring autonomous
|
|
ML experiment loops powered by Karpathy's autoresearch pattern.
|
|
"""
|
|
|
|
import logging
|
|
from pathlib import Path
|
|
|
|
from fastapi import APIRouter, HTTPException, Request
|
|
from fastapi.responses import HTMLResponse, JSONResponse
|
|
|
|
from config import settings
|
|
from dashboard.templating import templates
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
router = APIRouter(prefix="/experiments", tags=["experiments"])
|
|
|
|
|
|
def _workspace() -> Path:
|
|
return Path(settings.repo_root) / settings.autoresearch_workspace
|
|
|
|
|
|
@router.get("", response_class=HTMLResponse)
|
|
async def experiments_page(request: Request):
|
|
"""Experiment dashboard — lists past runs and allows starting new ones."""
|
|
from timmy.autoresearch import get_experiment_history
|
|
|
|
history = []
|
|
try:
|
|
history = get_experiment_history(_workspace())
|
|
except Exception as exc:
|
|
logger.debug("Failed to load experiment history: %s", exc)
|
|
|
|
return templates.TemplateResponse(
|
|
request,
|
|
"experiments.html",
|
|
{
|
|
"page_title": "Experiments — Autoresearch",
|
|
"enabled": settings.autoresearch_enabled,
|
|
"history": history[:50],
|
|
"metric_name": settings.autoresearch_metric,
|
|
"time_budget": settings.autoresearch_time_budget,
|
|
"max_iterations": settings.autoresearch_max_iterations,
|
|
},
|
|
)
|
|
|
|
|
|
@router.post("/start", response_class=JSONResponse)
|
|
async def start_experiment(request: Request):
|
|
"""Kick off an experiment loop in the background."""
|
|
if not settings.autoresearch_enabled:
|
|
raise HTTPException(
|
|
status_code=403,
|
|
detail="Autoresearch is disabled. Set AUTORESEARCH_ENABLED=true.",
|
|
)
|
|
|
|
from timmy.autoresearch import prepare_experiment
|
|
|
|
workspace = _workspace()
|
|
status = prepare_experiment(workspace)
|
|
|
|
return {"status": "started", "workspace": str(workspace), "prepare": status}
|
|
|
|
|
|
@router.get("/{run_id}", response_class=JSONResponse)
|
|
async def experiment_detail(run_id: str):
|
|
"""Get details for a specific experiment run."""
|
|
from timmy.autoresearch import get_experiment_history
|
|
|
|
history = get_experiment_history(_workspace())
|
|
for entry in history:
|
|
if entry.get("run_id") == run_id:
|
|
return entry
|
|
|
|
raise HTTPException(status_code=404, detail=f"Run {run_id} not found")
|