Files

74 lines
2.7 KiB
Python
Raw Permalink Normal View History

"""Tool: reconstruct current state after interruption (DB-backed)."""
from __future__ import annotations
import os
from helpers.tool import Tool, Response
from usr.plugins.a0_software_orchestrator.helpers.db_state_store import (
get_project_id,
get_kv, get_status, list_next_steps, list_todos, list_errors,
get_block_compact,
)
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())
class ResumeChecker(Tool):
"""Liest den aktuellen State aus der DB und liefert eine kompakte
Recovery-Übersicht für Session-Resume nach Crash/Timeout.
Args (kwargs):
project_name (str): Projektname (bevorzugt).
project_root (str): Legacy wird zu basename() aufgelöst.
"""
async def execute(
self,
project_name: str = "",
project_root: 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)
status = get_status(pid)
next_steps = list_next_steps(pid, status="pending")
open_todos = list_todos(pid, status="open")
open_errors = list_errors(pid, status="open")
bc = get_block_compact(pid)
phase = get_kv(pid, "phase", default="<unknown>")
if not status and not next_steps and not bc:
return Response(
message=f"No state found for recovery on project {name!r}.",
break_loop=False,
)
lines = [f"🔁 RESUME for project {name!r} (pid={pid})"]
lines.append(f" - Phase: {phase}")
lines.append(f" - Status: {status or '(none)'}")
lines.append(f" - Pending next steps: {len(next_steps)}")
lines.append(f" - Open todos: {len(open_todos)}")
lines.append(f" - Open errors: {len(open_errors)}")
if bc:
lines.append(
f" - Last block: {bc.get('last_block_id')} "
f"@ {bc.get('last_compact_at')}"
)
lines.append(f" - Next block: {bc.get('next_block')}")
return Response(message="\n".join(lines), break_loop=False)