feat(dashboard): add debug endpoint to clear dispatcher cooldowns

POST /api/debug/clear-cooldowns clears both in-memory toggle
cooldown map and SQLite dispatcher_cooldowns table.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Matt Johnson (via Claude) 2026-06-07 16:50:45 +00:00
commit fa5a869401
2 changed files with 36 additions and 0 deletions

View file

@ -0,0 +1,33 @@
"""Debug API endpoints for development/ops use."""
import logging
from fastapi import APIRouter, Request
logger = logging.getLogger(__name__)
router = APIRouter(tags=["debug"])
@router.post("/debug/clear-cooldowns")
async def clear_cooldowns(request: Request):
"""Delete all dispatcher cooldown state (in-memory + SQLite)."""
# Get dispatcher from pipeline components on the event bus
bus = getattr(request.app.state, "bus", None)
if bus is None:
return {"cleared": False, "error": "event bus not available"}
comps = getattr(bus, "_pipeline_components", None) or {}
dispatcher = comps.get("dispatcher")
if dispatcher is None:
return {"cleared": False, "error": "dispatcher not available"}
# Clear in-memory cooldown map
dispatcher._toggle_cooldown.clear()
# Clear SQLite cooldowns table
try:
from meshai.persistence import get_db
conn = get_db()
conn.execute("DELETE FROM dispatcher_cooldowns")
logger.info("debug: cleared all dispatcher cooldowns")
except Exception:
logger.exception("debug: failed to clear dispatcher_cooldowns table")
return {"cleared": True}

View file

@ -55,6 +55,7 @@ def create_app() -> FastAPI:
from .api.env_routes import router as env_router from .api.env_routes import router as env_router
from .api.alert_routes import router as alert_router from .api.alert_routes import router as alert_router
from .api.notification_routes import router as notification_router from .api.notification_routes import router as notification_router
from .api.debug_routes import router as debug_router
app.include_router(system_router, prefix="/api") app.include_router(system_router, prefix="/api")
app.include_router(adapter_config_router, prefix="/api") app.include_router(adapter_config_router, prefix="/api")
@ -65,6 +66,7 @@ def create_app() -> FastAPI:
app.include_router(alert_router, prefix="/api") app.include_router(alert_router, prefix="/api")
app.include_router(notification_router, prefix="/api") app.include_router(notification_router, prefix="/api")
app.include_router(debug_router, prefix="/api")
# WebSocket router (no prefix, path is /ws/live) # WebSocket router (no prefix, path is /ws/live)
app.include_router(ws_router) app.include_router(ws_router)
@ -118,6 +120,7 @@ async def start_dashboard(meshai_instance: "MeshAI") -> DashboardBroadcaster:
app.state.subscription_manager = meshai_instance.subscription_manager app.state.subscription_manager = meshai_instance.subscription_manager
app.state.notification_router = getattr(meshai_instance, "notification_router", None) app.state.notification_router = getattr(meshai_instance, "notification_router", None)
app.state.connector = meshai_instance.connector app.state.connector = meshai_instance.connector
app.state.bus = getattr(meshai_instance, "event_bus", None)
# Create broadcaster and attach to app state # Create broadcaster and attach to app state
broadcaster = DashboardBroadcaster() broadcaster = DashboardBroadcaster()