5769c1cd22
- Auto-Registration-Bug behoben (register_project/get_project_id/resolve_project Trennung) - 25 Tests gruen (Pytest) - block_compactor-Tool refactored (Option B: Soft-Check statt Hard-Block) - 4 Restbaustellen gefixt - DB-Schema: plugin_settings-Tabelle hinzugefuegt - 3 Schattenprojekte aus DB geloescht - Plan v3 + Refactor-Plan + Worklog dokumentiert
74 lines
2.7 KiB
Python
74 lines
2.7 KiB
Python
"""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)
|