mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-12 04:20:48 +08:00
Ship Cursor-only MCP admin and modular Admin/Chat UI.
Plugins/Skills install and edit via mcpServers JSON, with clearer row actions, soft reloads, and instant loading placeholders; also drop MCP market and harden related scheduler/logging/exec guards. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
2aff012b48
commit
f6f129931f
61 changed files with 18057 additions and 16327 deletions
65
runtime/scheduler/failure_class.py
Normal file
65
runtime/scheduler/failure_class.py
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
"""Classify scheduled_job_run errors for Admin dashboards and ops triage."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
|
||||
def classify_scheduled_job_error(error: str | None, *, status: str | None = None) -> str:
|
||||
"""Return a coarse failure_class for a scheduled job run.
|
||||
|
||||
Classes: overlap | timeout | delivery | mcp | auth | cancelled | runtime | "" (success/empty).
|
||||
"""
|
||||
st = str(status or "").strip().lower()
|
||||
err = str(error or "").strip()
|
||||
if st in {"success", "ok", "skipped"} and not err:
|
||||
return ""
|
||||
if st == "skipped" or "overlapping" in err.lower() or err.lower() == "overlapping_run":
|
||||
return "overlap"
|
||||
if not err and st not in {"failed", "error"}:
|
||||
return ""
|
||||
blob = err.lower()
|
||||
if "stale_running" in blob:
|
||||
return "stale"
|
||||
if any(x in blob for x in ("timeout", "timed out", "deadline", "read_timeout")):
|
||||
return "timeout"
|
||||
if any(
|
||||
x in blob
|
||||
for x in (
|
||||
"delivery",
|
||||
"enqueue_failed",
|
||||
"connection closed",
|
||||
"whatsapp",
|
||||
"weixin",
|
||||
"send_failed",
|
||||
"outbound",
|
||||
)
|
||||
):
|
||||
return "delivery"
|
||||
if any(x in blob for x in ("insufficient_scope", "unauthorized", "forbidden", "permission denied", "auth")):
|
||||
return "auth"
|
||||
if any(x in blob for x in ("mcp", "unregistered tool", "tool_not_registered")):
|
||||
return "mcp"
|
||||
if any(x in blob for x in ("cancel", "interrupted", "stopped")):
|
||||
return "cancelled"
|
||||
if err:
|
||||
return "runtime"
|
||||
if st in {"failed", "error"}:
|
||||
return "runtime"
|
||||
return ""
|
||||
|
||||
|
||||
def enrich_scheduled_job_run_dict(d: dict[str, Any]) -> dict[str, Any]:
|
||||
out = dict(d or {})
|
||||
fc = classify_scheduled_job_error(out.get("error"), status=str(out.get("status") or ""))
|
||||
if fc:
|
||||
out["failure_class"] = fc
|
||||
elif str(out.get("status") or "").strip().lower() in {"failed", "error"}:
|
||||
out["failure_class"] = "runtime"
|
||||
return out
|
||||
|
||||
|
||||
__all__ = [
|
||||
"classify_scheduled_job_error",
|
||||
"enrich_scheduled_job_run_dict",
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue