Claude Code commited on
Commit
bd0f4c9
·
1 Parent(s): db4a7e6

Claude Code: Target: Fix in Cain's event loop.

Browse files
Files changed (1) hide show
  1. app.py +68 -42
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.info("[API_CANCEL] /api/thoughts was cancelled")
2194
- raise
 
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.info("[API_CANCEL] /api/thoughts/stats was cancelled")
2206
- raise
 
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.info("[API_CANCEL] /api/thoughts/clear was cancelled")
2219
- raise
 
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.info("[API_CANCEL] /api/agent/status was cancelled")
2231
- raise
 
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.info("[API_CANCEL] /api/agent/registry was cancelled")
2243
- raise
 
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.info("[API_CANCEL] /api/agent/startup was cancelled")
2255
- raise
 
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.info("[API_CANCEL] /api/agent/reset-status was cancelled")
2268
- raise
 
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.info("[API_CANCEL] /api/analytics/stats was cancelled")
2282
- raise
 
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.info("[API_CANCEL] /api/analytics/summary was cancelled")
2294
- raise
 
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.info("[API_CANCEL] /api/analytics/history was cancelled")
2306
- raise
 
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.info("[API_CANCEL] /api/analytics/sync was cancelled")
2335
- raise
 
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.info("[API_CANCEL] /api/analytics/reset was cancelled")
2350
- raise
 
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.info("[API_CANCEL] /api/persistence/metrics was cancelled")
2375
- raise
 
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.info("[API_CANCEL] /api/persistence/sync was cancelled")
2397
- raise
 
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.info("[API_CANCEL] /health was cancelled")
2420
- raise
 
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.info("[API_CANCEL] /api/health was cancelled")
2463
- raise
 
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.info("[API_CANCEL] /api/logs was cancelled")
2500
- raise
 
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.info("[API_CANCEL] /office was cancelled")
2520
- raise
 
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.info("[API_CANCEL] /invite was cancelled")
2535
- raise
 
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.info("[API_CANCEL] /join was cancelled")
2550
- raise
 
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.info("[API_CANCEL] /agent-dashboard was cancelled")
2565
- raise
 
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)})