143 lines
5.2 KiB
Python
143 lines
5.2 KiB
Python
|
|
"""Tool: read/update entries inside orch_kv (DB-backed, replaces .a0/*.json)."""
|
|||
|
|
from __future__ import annotations
|
|||
|
|
|
|||
|
|
import json
|
|||
|
|
import os
|
|||
|
|
|
|||
|
|
from helpers.tool import Tool, Response
|
|||
|
|
from usr.plugins.a0_software_orchestrator.helpers.db_state_store import (
|
|||
|
|
get_project_id,
|
|||
|
|
get_kv, set_kv, delete_kv, list_kv_keys,
|
|||
|
|
set_status as db_set_status, get_status as db_get_status,
|
|||
|
|
)
|
|||
|
|
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 OrchestratorState(Tool):
|
|||
|
|
"""Read or update KV-entries for a project in `orch_kv` (patterns.db).
|
|||
|
|
|
|||
|
|
Args (kwargs):
|
|||
|
|
project_name (str): Projektname (bevorzugt).
|
|||
|
|
project_root (str): Legacy – wird zu basename() aufgelöst.
|
|||
|
|
action (str): "read", "update", "delete", "list_keys" (default "read").
|
|||
|
|
key (str): Schlüssel-Name (z.B. "phase", "orchestrator_mode",
|
|||
|
|
"task_graph", "tool_capabilities").
|
|||
|
|
Bei "read" ohne key: gibt alle Keys+Values als Dict zurück.
|
|||
|
|
value (str|dict): JSON-string oder dict für action=update.
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
async def execute(
|
|||
|
|
self,
|
|||
|
|
project_name: str = "",
|
|||
|
|
project_root: str = "",
|
|||
|
|
action: str = "read",
|
|||
|
|
key: str = "",
|
|||
|
|
value: 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)
|
|||
|
|
if action == "set_phase":
|
|||
|
|
action = "update"
|
|||
|
|
key = "phase"
|
|||
|
|
value = kwargs.get("phase", value)
|
|||
|
|
|
|||
|
|
if action == "get_phase":
|
|||
|
|
action = "read"
|
|||
|
|
key = "phase"
|
|||
|
|
|
|||
|
|
if action == "set_status":
|
|||
|
|
content = kwargs.get("status", value)
|
|||
|
|
if not content:
|
|||
|
|
return Response(message="ERROR: 'status' content required for action=set_status", break_loop=False)
|
|||
|
|
db_set_status(pid, str(content))
|
|||
|
|
return Response(message=f"Updated status for project '{name}'.", break_loop=False)
|
|||
|
|
|
|||
|
|
if action == "get_status":
|
|||
|
|
content = db_get_status(pid)
|
|||
|
|
return Response(message=content or f"No status set for project '{name}'.", break_loop=False)
|
|||
|
|
|
|||
|
|
if action == "list_keys":
|
|||
|
|
keys = list_kv_keys(pid)
|
|||
|
|
return Response(
|
|||
|
|
message=f"Keys for project '{name}': {', '.join(keys) if keys else '(none)'}",
|
|||
|
|
break_loop=False,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
if action == "read":
|
|||
|
|
if not key:
|
|||
|
|
# Alle Keys als Dict zurückgeben
|
|||
|
|
keys = list_kv_keys(pid)
|
|||
|
|
data = {k: get_kv(pid, k) for k in keys}
|
|||
|
|
return Response(
|
|||
|
|
message=json.dumps(data, indent=2, ensure_ascii=False, default=str),
|
|||
|
|
break_loop=False,
|
|||
|
|
)
|
|||
|
|
v = get_kv(pid, key, default=None)
|
|||
|
|
if v is None:
|
|||
|
|
return Response(
|
|||
|
|
message=f"Key '{key}' not set for project '{name}'.",
|
|||
|
|
break_loop=False,
|
|||
|
|
)
|
|||
|
|
return Response(
|
|||
|
|
message=json.dumps(v, indent=2, ensure_ascii=False, default=str),
|
|||
|
|
break_loop=False,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
if action == "update":
|
|||
|
|
if not key:
|
|||
|
|
return Response(
|
|||
|
|
message="ERROR: 'key' required for action=update",
|
|||
|
|
break_loop=False,
|
|||
|
|
)
|
|||
|
|
# value kann dict (direkt) oder str (JSON-encoded) sein
|
|||
|
|
if isinstance(value, str):
|
|||
|
|
try:
|
|||
|
|
parsed = json.loads(value) if value.strip() else None
|
|||
|
|
except json.JSONDecodeError:
|
|||
|
|
# Nicht-JSON-String → als reiner String speichern
|
|||
|
|
parsed = value
|
|||
|
|
else:
|
|||
|
|
parsed = value
|
|||
|
|
set_kv(pid, key, parsed)
|
|||
|
|
return Response(
|
|||
|
|
message=f"Updated key '{key}' for project '{name}'.",
|
|||
|
|
break_loop=False,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
if action == "delete":
|
|||
|
|
if not key:
|
|||
|
|
return Response(
|
|||
|
|
message="ERROR: 'key' required for action=delete",
|
|||
|
|
break_loop=False,
|
|||
|
|
)
|
|||
|
|
ok = delete_kv(pid, key)
|
|||
|
|
return Response(
|
|||
|
|
message=(
|
|||
|
|
f"Deleted key '{key}' for project '{name}'." if ok
|
|||
|
|
else f"Key '{key}' did not exist for project '{name}'."
|
|||
|
|
),
|
|||
|
|
break_loop=False,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
return Response(
|
|||
|
|
message=f"Unknown action {action!r}. Supported: read, update, delete, list_keys, set_phase, get_phase, set_status, get_status",
|
|||
|
|
break_loop=False,
|
|||
|
|
)
|