1
0
This repository has been archived on 2026-03-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Timmy-time-dashboard/src/dashboard/routes/spark.py

149 lines
4.6 KiB
Python

"""Spark Intelligence dashboard routes.
GET /spark — JSON status (API)
GET /spark/ui — HTML Spark Intelligence dashboard
GET /spark/timeline — HTMX partial: recent event timeline
GET /spark/insights — HTMX partial: advisories and insights
GET /spark/predictions — HTMX partial: EIDOS predictions
"""
import json
import logging
from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse
from dashboard.templating import templates
from spark.engine import spark_engine
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/spark", tags=["spark"])
@router.get("/ui", response_class=HTMLResponse)
async def spark_ui(request: Request):
"""Render the Spark Intelligence dashboard page."""
status = spark_engine.status()
advisories = spark_engine.get_advisories()
timeline = spark_engine.get_timeline(limit=20)
predictions = spark_engine.get_predictions(limit=10)
memories = spark_engine.get_memories(limit=10)
# Parse event data JSON for template display
timeline_enriched = []
for ev in timeline:
entry = {
"id": ev.id,
"event_type": ev.event_type,
"agent_id": ev.agent_id,
"task_id": ev.task_id,
"description": ev.description,
"importance": ev.importance,
"created_at": ev.created_at,
}
try:
entry["data"] = json.loads(ev.data)
except (json.JSONDecodeError, TypeError):
entry["data"] = {}
timeline_enriched.append(entry)
# Enrich predictions for display
predictions_enriched = []
for p in predictions:
entry = {
"id": p.id,
"task_id": p.task_id,
"prediction_type": p.prediction_type,
"accuracy": p.accuracy,
"created_at": p.created_at,
"evaluated_at": p.evaluated_at,
}
try:
entry["predicted"] = json.loads(p.predicted_value)
except (json.JSONDecodeError, TypeError):
entry["predicted"] = {}
try:
entry["actual"] = json.loads(p.actual_value) if p.actual_value else None
except (json.JSONDecodeError, TypeError):
entry["actual"] = None
predictions_enriched.append(entry)
return templates.TemplateResponse(
request,
"spark.html",
{
"status": status,
"advisories": advisories,
"timeline": timeline_enriched,
"predictions": predictions_enriched,
"memories": memories,
},
)
@router.get("", response_class=HTMLResponse)
async def spark_status_json():
"""Return Spark Intelligence status as JSON."""
from fastapi.responses import JSONResponse
status = spark_engine.status()
advisories = spark_engine.get_advisories()
return JSONResponse(
{
"status": status,
"advisories": [
{
"category": a.category,
"priority": a.priority,
"title": a.title,
"detail": a.detail,
"suggested_action": a.suggested_action,
"subject": a.subject,
"evidence_count": a.evidence_count,
}
for a in advisories
],
}
)
@router.get("/timeline", response_class=HTMLResponse)
async def spark_timeline(request: Request):
"""HTMX partial: recent event timeline."""
timeline = spark_engine.get_timeline(limit=20)
timeline_enriched = []
for ev in timeline:
entry = {
"id": ev.id,
"event_type": ev.event_type,
"agent_id": ev.agent_id,
"task_id": ev.task_id,
"description": ev.description,
"importance": ev.importance,
"created_at": ev.created_at,
}
try:
entry["data"] = json.loads(ev.data)
except (json.JSONDecodeError, TypeError):
entry["data"] = {}
timeline_enriched.append(entry)
return templates.TemplateResponse(
request,
"partials/spark_timeline.html",
{"timeline": timeline_enriched},
)
@router.get("/insights", response_class=HTMLResponse)
async def spark_insights(request: Request):
"""HTMX partial: advisories and consolidated memories."""
advisories = spark_engine.get_advisories()
memories = spark_engine.get_memories(limit=10)
return templates.TemplateResponse(
request,
"partials/spark_insights.html",
{"advisories": advisories, "memories": memories},
)