Spaces:
Sleeping
Sleeping
Claude Code commited on
Commit ·
bd0f4c9
1
Parent(s): db4a7e6
Claude Code: Target: Fix in Cain's event loop.
Browse files
app.py
CHANGED
|
@@ -2182,6 +2182,11 @@ def create_agent_office_with_ws():
|
|
| 2182 |
logger.debug(f"[QUEUE_CANCEL] {request.url.path} - client disconnected")
|
| 2183 |
from fastapi.responses import Response
|
| 2184 |
return Response(status_code=204, content=None)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2185 |
|
| 2186 |
# Define API route handlers
|
| 2187 |
@fastapi_app.get("/api/thoughts")
|
|
@@ -2190,8 +2195,9 @@ def create_agent_office_with_ws():
|
|
| 2190 |
try:
|
| 2191 |
return ws_manager.get_recent_thoughts(limit)
|
| 2192 |
except asyncio.CancelledError:
|
| 2193 |
-
logger.
|
| 2194 |
-
|
|
|
|
| 2195 |
except Exception as e:
|
| 2196 |
logger.error(f"[API_ERROR] /api/thoughts: {e}")
|
| 2197 |
return {"error": str(e)}
|
|
@@ -2202,8 +2208,9 @@ def create_agent_office_with_ws():
|
|
| 2202 |
try:
|
| 2203 |
return ws_manager.get_stats()
|
| 2204 |
except asyncio.CancelledError:
|
| 2205 |
-
logger.
|
| 2206 |
-
|
|
|
|
| 2207 |
except Exception as e:
|
| 2208 |
logger.error(f"[API_ERROR] /api/thoughts/stats: {e}")
|
| 2209 |
return {"error": str(e)}
|
|
@@ -2215,8 +2222,9 @@ def create_agent_office_with_ws():
|
|
| 2215 |
ws_manager.clear_history()
|
| 2216 |
return {"status": "cleared"}
|
| 2217 |
except asyncio.CancelledError:
|
| 2218 |
-
logger.
|
| 2219 |
-
|
|
|
|
| 2220 |
except Exception as e:
|
| 2221 |
logger.error(f"[API_ERROR] /api/thoughts/clear: {e}")
|
| 2222 |
return {"error": str(e)}
|
|
@@ -2227,8 +2235,9 @@ def create_agent_office_with_ws():
|
|
| 2227 |
try:
|
| 2228 |
return load_cain_status()
|
| 2229 |
except asyncio.CancelledError:
|
| 2230 |
-
logger.
|
| 2231 |
-
|
|
|
|
| 2232 |
except Exception as e:
|
| 2233 |
logger.error(f"[API_ERROR] /api/agent/status: {e}")
|
| 2234 |
return {"error": str(e)}
|
|
@@ -2239,8 +2248,9 @@ def create_agent_office_with_ws():
|
|
| 2239 |
try:
|
| 2240 |
return load_agent_registry()
|
| 2241 |
except asyncio.CancelledError:
|
| 2242 |
-
logger.
|
| 2243 |
-
|
|
|
|
| 2244 |
except Exception as e:
|
| 2245 |
logger.error(f"[API_ERROR] /api/agent/registry: {e}")
|
| 2246 |
return {"error": str(e)}
|
|
@@ -2251,8 +2261,9 @@ def create_agent_office_with_ws():
|
|
| 2251 |
try:
|
| 2252 |
return get_startup_report()
|
| 2253 |
except asyncio.CancelledError:
|
| 2254 |
-
logger.
|
| 2255 |
-
|
|
|
|
| 2256 |
except Exception as e:
|
| 2257 |
logger.error(f"[API_ERROR] /api/agent/startup: {e}")
|
| 2258 |
return {"error": str(e)}
|
|
@@ -2264,8 +2275,9 @@ def create_agent_office_with_ws():
|
|
| 2264 |
status = ensure_cain_status_file()
|
| 2265 |
return {"success": True, "status": status}
|
| 2266 |
except asyncio.CancelledError:
|
| 2267 |
-
logger.
|
| 2268 |
-
|
|
|
|
| 2269 |
except Exception as e:
|
| 2270 |
logger.error(f"[API_ERROR] /api/agent/reset-status: {e}")
|
| 2271 |
return {"success": False, "error": str(e)}
|
|
@@ -2278,8 +2290,9 @@ def create_agent_office_with_ws():
|
|
| 2278 |
try:
|
| 2279 |
return get_analytics_stats_json()
|
| 2280 |
except asyncio.CancelledError:
|
| 2281 |
-
logger.
|
| 2282 |
-
|
|
|
|
| 2283 |
except Exception as e:
|
| 2284 |
logger.error(f"[API_ERROR] /api/analytics/stats: {e}")
|
| 2285 |
return {"error": str(e)}
|
|
@@ -2290,8 +2303,9 @@ def create_agent_office_with_ws():
|
|
| 2290 |
try:
|
| 2291 |
return {"summary": get_analytics_summary()}
|
| 2292 |
except asyncio.CancelledError:
|
| 2293 |
-
logger.
|
| 2294 |
-
|
|
|
|
| 2295 |
except Exception as e:
|
| 2296 |
logger.error(f"[API_ERROR] /api/analytics/summary: {e}")
|
| 2297 |
return {"error": str(e)}
|
|
@@ -2302,8 +2316,9 @@ def create_agent_office_with_ws():
|
|
| 2302 |
try:
|
| 2303 |
return get_conversation_history_json(limit)
|
| 2304 |
except asyncio.CancelledError:
|
| 2305 |
-
logger.
|
| 2306 |
-
|
|
|
|
| 2307 |
except Exception as e:
|
| 2308 |
logger.error(f"[API_ERROR] /api/analytics/history: {e}")
|
| 2309 |
return {"error": str(e)}
|
|
@@ -2331,8 +2346,9 @@ def create_agent_office_with_ws():
|
|
| 2331 |
|
| 2332 |
return result
|
| 2333 |
except asyncio.CancelledError:
|
| 2334 |
-
logger.
|
| 2335 |
-
|
|
|
|
| 2336 |
except Exception as e:
|
| 2337 |
httpcore_breaker.record_failure()
|
| 2338 |
logger.error(f"[API_ERROR] /api/analytics/sync: {e}")
|
|
@@ -2346,8 +2362,9 @@ def create_agent_office_with_ws():
|
|
| 2346 |
analytics.reset()
|
| 2347 |
return {"status": "reset"}
|
| 2348 |
except asyncio.CancelledError:
|
| 2349 |
-
logger.
|
| 2350 |
-
|
|
|
|
| 2351 |
except Exception as e:
|
| 2352 |
logger.error(f"[API_ERROR] /api/analytics/reset: {e}")
|
| 2353 |
return {"error": str(e)}
|
|
@@ -2371,8 +2388,9 @@ def create_agent_office_with_ws():
|
|
| 2371 |
"error": "Conversation storage not initialized"
|
| 2372 |
}
|
| 2373 |
except asyncio.CancelledError:
|
| 2374 |
-
logger.
|
| 2375 |
-
|
|
|
|
| 2376 |
except Exception as e:
|
| 2377 |
write_error_log("api_error", "persistence_metrics", f"Failed to get metrics: {e}", exc_info=sys.exc_info())
|
| 2378 |
return {
|
|
@@ -2393,8 +2411,9 @@ def create_agent_office_with_ws():
|
|
| 2393 |
"error": "Conversation storage not initialized"
|
| 2394 |
}
|
| 2395 |
except asyncio.CancelledError:
|
| 2396 |
-
logger.
|
| 2397 |
-
|
|
|
|
| 2398 |
except Exception as e:
|
| 2399 |
write_error_log("api_error", "persistence_sync", f"Sync failed: {e}", exc_info=sys.exc_info())
|
| 2400 |
return {
|
|
@@ -2416,8 +2435,9 @@ def create_agent_office_with_ws():
|
|
| 2416 |
"timestamp": datetime.utcnow().isoformat() + "Z"
|
| 2417 |
}
|
| 2418 |
except asyncio.CancelledError:
|
| 2419 |
-
logger.
|
| 2420 |
-
|
|
|
|
| 2421 |
except Exception as e:
|
| 2422 |
return {
|
| 2423 |
"status": "unhealthy",
|
|
@@ -2459,8 +2479,9 @@ def create_agent_office_with_ws():
|
|
| 2459 |
|
| 2460 |
return result
|
| 2461 |
except asyncio.CancelledError:
|
| 2462 |
-
logger.
|
| 2463 |
-
|
|
|
|
| 2464 |
except Exception as e:
|
| 2465 |
write_error_log("api_error", "health", f"Health check failed: {e}", exc_info=sys.exc_info())
|
| 2466 |
return {
|
|
@@ -2496,8 +2517,9 @@ def create_agent_office_with_ws():
|
|
| 2496 |
"total": len(logs)
|
| 2497 |
}
|
| 2498 |
except asyncio.CancelledError:
|
| 2499 |
-
logger.
|
| 2500 |
-
|
|
|
|
| 2501 |
except Exception as e:
|
| 2502 |
return {
|
| 2503 |
"success": False,
|
|
@@ -2516,8 +2538,9 @@ def create_agent_office_with_ws():
|
|
| 2516 |
return FileResponse(office_html, media_type="text/html")
|
| 2517 |
return JSONResponse(status_code=404, content={"error": "Office UI not found"})
|
| 2518 |
except asyncio.CancelledError:
|
| 2519 |
-
logger.
|
| 2520 |
-
|
|
|
|
| 2521 |
except Exception as e:
|
| 2522 |
logger.error(f"[API_ERROR] /office: {e}")
|
| 2523 |
return JSONResponse(status_code=500, content={"error": str(e)})
|
|
@@ -2531,8 +2554,9 @@ def create_agent_office_with_ws():
|
|
| 2531 |
return FileResponse(invite_html, media_type="text/html")
|
| 2532 |
return JSONResponse(status_code=404, content={"error": "Invite page not found"})
|
| 2533 |
except asyncio.CancelledError:
|
| 2534 |
-
logger.
|
| 2535 |
-
|
|
|
|
| 2536 |
except Exception as e:
|
| 2537 |
logger.error(f"[API_ERROR] /invite: {e}")
|
| 2538 |
return JSONResponse(status_code=500, content={"error": str(e)})
|
|
@@ -2546,8 +2570,9 @@ def create_agent_office_with_ws():
|
|
| 2546 |
return FileResponse(join_html, media_type="text/html")
|
| 2547 |
return JSONResponse(status_code=404, content={"error": "Join page not found"})
|
| 2548 |
except asyncio.CancelledError:
|
| 2549 |
-
logger.
|
| 2550 |
-
|
|
|
|
| 2551 |
except Exception as e:
|
| 2552 |
logger.error(f"[API_ERROR] /join: {e}")
|
| 2553 |
return JSONResponse(status_code=500, content={"error": str(e)})
|
|
@@ -2561,8 +2586,9 @@ def create_agent_office_with_ws():
|
|
| 2561 |
return FileResponse(dashboard_html, media_type="text/html")
|
| 2562 |
return JSONResponse(status_code=404, content={"error": "Agent dashboard not found"})
|
| 2563 |
except asyncio.CancelledError:
|
| 2564 |
-
logger.
|
| 2565 |
-
|
|
|
|
| 2566 |
except Exception as e:
|
| 2567 |
logger.error(f"[API_ERROR] /agent-dashboard: {e}")
|
| 2568 |
return JSONResponse(status_code=500, content={"error": str(e)})
|
|
|
|
| 2182 |
logger.debug(f"[QUEUE_CANCEL] {request.url.path} - client disconnected")
|
| 2183 |
from fastapi.responses import Response
|
| 2184 |
return Response(status_code=204, content=None)
|
| 2185 |
+
except Exception as e:
|
| 2186 |
+
# Catch any other exceptions that might be raised from Gradio's internal queues
|
| 2187 |
+
logger.debug(f"[MIDDLEWARE] Exception caught for {request.url.path}: {type(e).__name__}")
|
| 2188 |
+
# Re-raise non-CancelledError exceptions
|
| 2189 |
+
raise
|
| 2190 |
|
| 2191 |
# Define API route handlers
|
| 2192 |
@fastapi_app.get("/api/thoughts")
|
|
|
|
| 2195 |
try:
|
| 2196 |
return ws_manager.get_recent_thoughts(limit)
|
| 2197 |
except asyncio.CancelledError:
|
| 2198 |
+
logger.debug("[API_CANCEL] /api/thoughts was cancelled")
|
| 2199 |
+
from fastapi.responses import Response
|
| 2200 |
+
return Response(status_code=204, content=None)
|
| 2201 |
except Exception as e:
|
| 2202 |
logger.error(f"[API_ERROR] /api/thoughts: {e}")
|
| 2203 |
return {"error": str(e)}
|
|
|
|
| 2208 |
try:
|
| 2209 |
return ws_manager.get_stats()
|
| 2210 |
except asyncio.CancelledError:
|
| 2211 |
+
logger.debug("[API_CANCEL] /api/thoughts/stats was cancelled")
|
| 2212 |
+
from fastapi.responses import Response
|
| 2213 |
+
return Response(status_code=204, content=None)
|
| 2214 |
except Exception as e:
|
| 2215 |
logger.error(f"[API_ERROR] /api/thoughts/stats: {e}")
|
| 2216 |
return {"error": str(e)}
|
|
|
|
| 2222 |
ws_manager.clear_history()
|
| 2223 |
return {"status": "cleared"}
|
| 2224 |
except asyncio.CancelledError:
|
| 2225 |
+
logger.debug("[API_CANCEL] /api/thoughts/clear was cancelled")
|
| 2226 |
+
from fastapi.responses import Response
|
| 2227 |
+
return Response(status_code=204, content=None)
|
| 2228 |
except Exception as e:
|
| 2229 |
logger.error(f"[API_ERROR] /api/thoughts/clear: {e}")
|
| 2230 |
return {"error": str(e)}
|
|
|
|
| 2235 |
try:
|
| 2236 |
return load_cain_status()
|
| 2237 |
except asyncio.CancelledError:
|
| 2238 |
+
logger.debug("[API_CANCEL] /api/agent/status was cancelled")
|
| 2239 |
+
from fastapi.responses import Response
|
| 2240 |
+
return Response(status_code=204, content=None)
|
| 2241 |
except Exception as e:
|
| 2242 |
logger.error(f"[API_ERROR] /api/agent/status: {e}")
|
| 2243 |
return {"error": str(e)}
|
|
|
|
| 2248 |
try:
|
| 2249 |
return load_agent_registry()
|
| 2250 |
except asyncio.CancelledError:
|
| 2251 |
+
logger.debug("[API_CANCEL] /api/agent/registry was cancelled")
|
| 2252 |
+
from fastapi.responses import Response
|
| 2253 |
+
return Response(status_code=204, content=None)
|
| 2254 |
except Exception as e:
|
| 2255 |
logger.error(f"[API_ERROR] /api/agent/registry: {e}")
|
| 2256 |
return {"error": str(e)}
|
|
|
|
| 2261 |
try:
|
| 2262 |
return get_startup_report()
|
| 2263 |
except asyncio.CancelledError:
|
| 2264 |
+
logger.debug("[API_CANCEL] /api/agent/startup was cancelled")
|
| 2265 |
+
from fastapi.responses import Response
|
| 2266 |
+
return Response(status_code=204, content=None)
|
| 2267 |
except Exception as e:
|
| 2268 |
logger.error(f"[API_ERROR] /api/agent/startup: {e}")
|
| 2269 |
return {"error": str(e)}
|
|
|
|
| 2275 |
status = ensure_cain_status_file()
|
| 2276 |
return {"success": True, "status": status}
|
| 2277 |
except asyncio.CancelledError:
|
| 2278 |
+
logger.debug("[API_CANCEL] /api/agent/reset-status was cancelled")
|
| 2279 |
+
from fastapi.responses import Response
|
| 2280 |
+
return Response(status_code=204, content=None)
|
| 2281 |
except Exception as e:
|
| 2282 |
logger.error(f"[API_ERROR] /api/agent/reset-status: {e}")
|
| 2283 |
return {"success": False, "error": str(e)}
|
|
|
|
| 2290 |
try:
|
| 2291 |
return get_analytics_stats_json()
|
| 2292 |
except asyncio.CancelledError:
|
| 2293 |
+
logger.debug("[API_CANCEL] /api/analytics/stats was cancelled")
|
| 2294 |
+
from fastapi.responses import Response
|
| 2295 |
+
return Response(status_code=204, content=None)
|
| 2296 |
except Exception as e:
|
| 2297 |
logger.error(f"[API_ERROR] /api/analytics/stats: {e}")
|
| 2298 |
return {"error": str(e)}
|
|
|
|
| 2303 |
try:
|
| 2304 |
return {"summary": get_analytics_summary()}
|
| 2305 |
except asyncio.CancelledError:
|
| 2306 |
+
logger.debug("[API_CANCEL] /api/analytics/summary was cancelled")
|
| 2307 |
+
from fastapi.responses import Response
|
| 2308 |
+
return Response(status_code=204, content=None)
|
| 2309 |
except Exception as e:
|
| 2310 |
logger.error(f"[API_ERROR] /api/analytics/summary: {e}")
|
| 2311 |
return {"error": str(e)}
|
|
|
|
| 2316 |
try:
|
| 2317 |
return get_conversation_history_json(limit)
|
| 2318 |
except asyncio.CancelledError:
|
| 2319 |
+
logger.debug("[API_CANCEL] /api/analytics/history was cancelled")
|
| 2320 |
+
from fastapi.responses import Response
|
| 2321 |
+
return Response(status_code=204, content=None)
|
| 2322 |
except Exception as e:
|
| 2323 |
logger.error(f"[API_ERROR] /api/analytics/history: {e}")
|
| 2324 |
return {"error": str(e)}
|
|
|
|
| 2346 |
|
| 2347 |
return result
|
| 2348 |
except asyncio.CancelledError:
|
| 2349 |
+
logger.debug("[API_CANCEL] /api/analytics/sync was cancelled")
|
| 2350 |
+
from fastapi.responses import Response
|
| 2351 |
+
return Response(status_code=204, content=None)
|
| 2352 |
except Exception as e:
|
| 2353 |
httpcore_breaker.record_failure()
|
| 2354 |
logger.error(f"[API_ERROR] /api/analytics/sync: {e}")
|
|
|
|
| 2362 |
analytics.reset()
|
| 2363 |
return {"status": "reset"}
|
| 2364 |
except asyncio.CancelledError:
|
| 2365 |
+
logger.debug("[API_CANCEL] /api/analytics/reset was cancelled")
|
| 2366 |
+
from fastapi.responses import Response
|
| 2367 |
+
return Response(status_code=204, content=None)
|
| 2368 |
except Exception as e:
|
| 2369 |
logger.error(f"[API_ERROR] /api/analytics/reset: {e}")
|
| 2370 |
return {"error": str(e)}
|
|
|
|
| 2388 |
"error": "Conversation storage not initialized"
|
| 2389 |
}
|
| 2390 |
except asyncio.CancelledError:
|
| 2391 |
+
logger.debug("[API_CANCEL] /api/persistence/metrics was cancelled")
|
| 2392 |
+
from fastapi.responses import Response
|
| 2393 |
+
return Response(status_code=204, content=None)
|
| 2394 |
except Exception as e:
|
| 2395 |
write_error_log("api_error", "persistence_metrics", f"Failed to get metrics: {e}", exc_info=sys.exc_info())
|
| 2396 |
return {
|
|
|
|
| 2411 |
"error": "Conversation storage not initialized"
|
| 2412 |
}
|
| 2413 |
except asyncio.CancelledError:
|
| 2414 |
+
logger.debug("[API_CANCEL] /api/persistence/sync was cancelled")
|
| 2415 |
+
from fastapi.responses import Response
|
| 2416 |
+
return Response(status_code=204, content=None)
|
| 2417 |
except Exception as e:
|
| 2418 |
write_error_log("api_error", "persistence_sync", f"Sync failed: {e}", exc_info=sys.exc_info())
|
| 2419 |
return {
|
|
|
|
| 2435 |
"timestamp": datetime.utcnow().isoformat() + "Z"
|
| 2436 |
}
|
| 2437 |
except asyncio.CancelledError:
|
| 2438 |
+
logger.debug("[API_CANCEL] /health was cancelled")
|
| 2439 |
+
from fastapi.responses import Response
|
| 2440 |
+
return Response(status_code=204, content=None)
|
| 2441 |
except Exception as e:
|
| 2442 |
return {
|
| 2443 |
"status": "unhealthy",
|
|
|
|
| 2479 |
|
| 2480 |
return result
|
| 2481 |
except asyncio.CancelledError:
|
| 2482 |
+
logger.debug("[API_CANCEL] /api/health was cancelled")
|
| 2483 |
+
from fastapi.responses import Response
|
| 2484 |
+
return Response(status_code=204, content=None)
|
| 2485 |
except Exception as e:
|
| 2486 |
write_error_log("api_error", "health", f"Health check failed: {e}", exc_info=sys.exc_info())
|
| 2487 |
return {
|
|
|
|
| 2517 |
"total": len(logs)
|
| 2518 |
}
|
| 2519 |
except asyncio.CancelledError:
|
| 2520 |
+
logger.debug("[API_CANCEL] /api/logs was cancelled")
|
| 2521 |
+
from fastapi.responses import Response
|
| 2522 |
+
return Response(status_code=204, content=None)
|
| 2523 |
except Exception as e:
|
| 2524 |
return {
|
| 2525 |
"success": False,
|
|
|
|
| 2538 |
return FileResponse(office_html, media_type="text/html")
|
| 2539 |
return JSONResponse(status_code=404, content={"error": "Office UI not found"})
|
| 2540 |
except asyncio.CancelledError:
|
| 2541 |
+
logger.debug("[API_CANCEL] /office was cancelled")
|
| 2542 |
+
from fastapi.responses import Response
|
| 2543 |
+
return Response(status_code=204, content=None)
|
| 2544 |
except Exception as e:
|
| 2545 |
logger.error(f"[API_ERROR] /office: {e}")
|
| 2546 |
return JSONResponse(status_code=500, content={"error": str(e)})
|
|
|
|
| 2554 |
return FileResponse(invite_html, media_type="text/html")
|
| 2555 |
return JSONResponse(status_code=404, content={"error": "Invite page not found"})
|
| 2556 |
except asyncio.CancelledError:
|
| 2557 |
+
logger.debug("[API_CANCEL] /invite was cancelled")
|
| 2558 |
+
from fastapi.responses import Response
|
| 2559 |
+
return Response(status_code=204, content=None)
|
| 2560 |
except Exception as e:
|
| 2561 |
logger.error(f"[API_ERROR] /invite: {e}")
|
| 2562 |
return JSONResponse(status_code=500, content={"error": str(e)})
|
|
|
|
| 2570 |
return FileResponse(join_html, media_type="text/html")
|
| 2571 |
return JSONResponse(status_code=404, content={"error": "Join page not found"})
|
| 2572 |
except asyncio.CancelledError:
|
| 2573 |
+
logger.debug("[API_CANCEL] /join was cancelled")
|
| 2574 |
+
from fastapi.responses import Response
|
| 2575 |
+
return Response(status_code=204, content=None)
|
| 2576 |
except Exception as e:
|
| 2577 |
logger.error(f"[API_ERROR] /join: {e}")
|
| 2578 |
return JSONResponse(status_code=500, content={"error": str(e)})
|
|
|
|
| 2586 |
return FileResponse(dashboard_html, media_type="text/html")
|
| 2587 |
return JSONResponse(status_code=404, content={"error": "Agent dashboard not found"})
|
| 2588 |
except asyncio.CancelledError:
|
| 2589 |
+
logger.debug("[API_CANCEL] /agent-dashboard was cancelled")
|
| 2590 |
+
from fastapi.responses import Response
|
| 2591 |
+
return Response(status_code=204, content=None)
|
| 2592 |
except Exception as e:
|
| 2593 |
logger.error(f"[API_ERROR] /agent-dashboard: {e}")
|
| 2594 |
return JSONResponse(status_code=500, content={"error": str(e)})
|