114 lines
4.0 KiB
Python
114 lines
4.0 KiB
Python
|
|
"""Tool: record/inspect tool health (DB-backed, replaces .a0/tool_registry.json)."""
|
|||
|
|
from __future__ import annotations
|
|||
|
|
|
|||
|
|
import json
|
|||
|
|
import os
|
|||
|
|
from datetime import datetime
|
|||
|
|
from typing import Any, Dict
|
|||
|
|
|
|||
|
|
from helpers.tool import Tool, Response
|
|||
|
|
from usr.plugins.a0_software_orchestrator.helpers.db_state_store import get_project_id, set_kv, get_kv
|
|||
|
|
from usr.plugins.a0_software_orchestrator.helpers.exceptions import PluginDBError
|
|||
|
|
|
|||
|
|
|
|||
|
|
def _resolve_name(project_name: str = "", project_root: str = "") -> str:
|
|||
|
|
if project_name:
|
|||
|
|
return project_name.strip()
|
|||
|
|
if project_root:
|
|||
|
|
return os.path.basename(project_root.rstrip("/"))
|
|||
|
|
return os.path.basename(os.getcwd())
|
|||
|
|
|
|||
|
|
|
|||
|
|
def _now() -> str:
|
|||
|
|
return datetime.utcnow().isoformat() + "Z"
|
|||
|
|
|
|||
|
|
|
|||
|
|
class ToolRegistry(Tool):
|
|||
|
|
"""Register, list, or deregister tools in `orch_kv["tool_registry"]`.
|
|||
|
|
|
|||
|
|
Args (kwargs):
|
|||
|
|
project_name (str): Projektname (bevorzugt).
|
|||
|
|
project_root (str): Legacy – wird zu basename() aufgelöst.
|
|||
|
|
action (str): "register" (default), "list", "deregister".
|
|||
|
|
tool_name (str): Name des Tools (für register/deregister).
|
|||
|
|
status (str): Status – "ok", "degraded", "failed" (für register).
|
|||
|
|
details (str): Optionale Details (für register).
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
async def execute(
|
|||
|
|
self,
|
|||
|
|
project_name: str = "",
|
|||
|
|
project_root: str = "",
|
|||
|
|
action: str = "list",
|
|||
|
|
tool_name: str = "",
|
|||
|
|
status: str = "ok",
|
|||
|
|
details: str = "",
|
|||
|
|
**kwargs,
|
|||
|
|
):
|
|||
|
|
name = _resolve_name(project_name, project_root)
|
|||
|
|
try:
|
|||
|
|
pid = get_project_id(name)
|
|||
|
|
if pid is None:
|
|||
|
|
raise LookupError(f"project '{name}' is not registered")
|
|||
|
|
except (ValueError, LookupError) as e:
|
|||
|
|
return Response(message=f"ERROR: {e}", break_loop=False)
|
|||
|
|
|
|||
|
|
except PluginDBError as e:
|
|||
|
|
return Response(message=f"Database error: {e}", break_loop=False)
|
|||
|
|
# Wir nutzen orch_kv mit key="tool_registry" als JSON-Blob
|
|||
|
|
reg: Dict[str, Any] = get_kv(pid, "tool_registry", default={"tools": {}})
|
|||
|
|
if "tools" not in reg:
|
|||
|
|
reg = {"tools": {}}
|
|||
|
|
|
|||
|
|
if action == "register":
|
|||
|
|
if not tool_name:
|
|||
|
|
return Response(
|
|||
|
|
message="ERROR: 'tool_name' required for action=register",
|
|||
|
|
break_loop=False,
|
|||
|
|
)
|
|||
|
|
reg["tools"][tool_name] = {
|
|||
|
|
"status": status,
|
|||
|
|
"last_checked": _now(),
|
|||
|
|
}
|
|||
|
|
if details:
|
|||
|
|
reg["tools"][tool_name]["details"] = details
|
|||
|
|
set_kv(pid, "tool_registry", reg)
|
|||
|
|
return Response(
|
|||
|
|
message=f"Registered {tool_name!r} as {status!r} for project {name!r}.",
|
|||
|
|
break_loop=False,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
if action == "deregister":
|
|||
|
|
if not tool_name:
|
|||
|
|
return Response(
|
|||
|
|
message="ERROR: 'tool_name' required for action=deregister",
|
|||
|
|
break_loop=False,
|
|||
|
|
)
|
|||
|
|
if tool_name in reg["tools"]:
|
|||
|
|
del reg["tools"][tool_name]
|
|||
|
|
set_kv(pid, "tool_registry", reg)
|
|||
|
|
return Response(
|
|||
|
|
message=f"Deregistered {tool_name!r} for project {name!r}.",
|
|||
|
|
break_loop=False,
|
|||
|
|
)
|
|||
|
|
return Response(
|
|||
|
|
message=f"Tool {tool_name!r} not registered for project {name!r}.",
|
|||
|
|
break_loop=False,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
if action == "list":
|
|||
|
|
if not reg["tools"]:
|
|||
|
|
return Response(
|
|||
|
|
message=f"No tools registered for project {name!r}.",
|
|||
|
|
break_loop=False,
|
|||
|
|
)
|
|||
|
|
return Response(
|
|||
|
|
message=json.dumps(reg, indent=2, ensure_ascii=False),
|
|||
|
|
break_loop=False,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
return Response(
|
|||
|
|
message=f"Unknown action {action!r}. Supported: register, deregister, list",
|
|||
|
|
break_loop=False,
|
|||
|
|
)
|