Files
Software Orchestrator 5769c1cd22 Initial commit: a0_software_orchestrator v1.0
- 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
2026-06-16 22:13:06 +00:00

143 lines
5.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""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,
)