Simplify Athena operator architecture

This commit is contained in:
Mikei386 committed 2026-08-25 21:53:12 +02:00
1 parent c25e57af57
commit 0a640e76ea
22 files changed
+577 -1522

No files matched your search

+66 -84
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
"""Single MCP facade for end-to-end Athena platform operation."""
"""Compact MCP facade for the Athena host operator."""
from __future__ import annotations
@@ -10,7 +10,7 @@ import sys
from typing import Any
VERSION = "2.2.0"
VERSION = "3.0.0"
SOCKET_PATH = os.environ.get("ATHENA_OPERATOR_SOCKET", "/operator/operator.sock")
if hasattr(sys.stdin, "reconfigure"):
@@ -22,50 +22,48 @@ if hasattr(sys.stdout, "reconfigure"):
TOOLS = [
{
"name": "athena_operator_inspect",
"description": (
"USE FIRST for Athena administration. Inspect live platform state without changing it. "
"Subjects: overview, git_status, containers, models, jobs. This is the authoritative "
"starting point before MCP, Docker, model, profile, benchmark or recovery work."
),
"description": "START HERE once for Athena work. Inspect the requested live area without changing it.",
"inputSchema": {
"type": "object",
"properties": {"subject": {"type": "string", "enum": ["overview", "git_status", "containers", "models", "jobs"], "default": "overview"}},
"properties": {
"subject": {"type": "string", "enum": ["overview", "git_status", "containers", "models", "jobs"], "default": "overview"},
},
"additionalProperties": False,
},
},
{
"name": "athena_operator_search_source",
"description": "Find the exact source path and line before reading or editing it. Returns at most 20 matches.",
"inputSchema": {
"type": "object",
"properties": {"query": {"type": "string", "minLength": 1, "maxLength": 120}},
"required": ["query"],
"additionalProperties": False,
},
},
{
"name": "athena_operator_read_source",
"description": (
"Read a versioned Athena repository file with SHA-256 and bounded line range. Use this "
"instead of guessing current Compose, MCP, router, model, OpenWebUI or recovery code."
"Read only the needed section of one known source file. Default 80 and maximum "
"200 lines. A not-found result must not be retried by guessing more paths."
),
"inputSchema": {
"type": "object",
"properties": {
"path": {"type": "string", "pattern": "^[A-Za-z0-9_.+/-]{1,240}$"},
"start_line": {"type": "integer", "minimum": 1, "maximum": 1000000, "default": 1},
"line_count": {"type": "integer", "minimum": 1, "maximum": 1000, "default": 300},
"line_count": {"type": "integer", "minimum": 1, "maximum": 200, "default": 80},
},
"required": ["path"], "additionalProperties": False,
"required": ["path"],
"additionalProperties": False,
},
},
{
"name": "athena_operator_search_source",
"description": "Search the complete versioned Athena repository for exact text before designing or modifying a component.",
"inputSchema": {"type": "object", "properties": {"query": {"type": "string", "minLength": 1, "maxLength": 200}}, "required": ["query"], "additionalProperties": False},
},
{
"name": "athena_operator_terminal",
"description": (
"GENERAL ATHENA TERMINAL. Run one bounded shell command on the Athena host when the "
"structured operator tools are too narrow. This is the broad escape hatch for Docker, "
"Compose, Git, MCP development, model inspection, downloads, HTTP/API tests, files, logs "
"and SSH to configured remote systems. Prefer a single focused command and cap noisy output "
"with the command itself. The server blocks power control and changes to Athena's SSH, LAN, "
"WireGuard, firewall, boot, kernel, mounts and partitions so remote reachability cannot be "
"accidentally destroyed. Other commands execute immediately and must be verified afterwards. "
"Do not clone the canonical repository, request/copy an SSH key, or use Terminal as a substitute "
"for the durable file_update, git_publish and recovery workflow."
"General bounded terminal on Athena for focused Docker, Git, file, HTTP, model "
"and test work when no structured operation fits. Limit noisy output yourself. "
"Power control and Athena reachability changes are blocked."
),
"inputSchema": {
"type": "object",
@@ -73,69 +71,43 @@ TOOLS = [
"command": {"type": "string", "minLength": 1, "maxLength": 8000},
"cwd": {"type": "string", "maxLength": 500, "default": "/opt/mike-ai/stack"},
"timeout_seconds": {"type": "integer", "minimum": 1, "maximum": 3600, "default": 300},
"max_output_chars": {"type": "integer", "minimum": 1000, "maximum": 30000, "default": 12000},
"max_output_chars": {"type": "integer", "minimum": 1000, "maximum": 30000, "default": 8000},
},
"required": ["command"],
"additionalProperties": False,
},
},
{
"name": "athena_operator_prepare",
"name": "athena_operator_change",
"description": (
"PREPARE a state-changing Athena operation. This never changes state. It returns a "
"content-bound ticket, exact preview and confirmation phrase. Supported operations: "
"patch_update (preferred for small changes), file_update (only for new or fully replaced files), "
"mcp_release (preferred one-ticket end-to-end MCP delivery), run_checks, compose_deploy, "
"container_action, openwebui_sync, git_publish, model_download, benchmark, recovery. Show the complete "
"preview to the user and stop. Never execute in the same autonomous tool sequence. This is the "
"supported durable source and Git path: never clone the repository inside a sandbox and never "
"request or copy an SSH key. "
"patch_update payload: {files:[{path,patch,expected_sha256?}]} using standard unified diffs; "
"file_update payload: {files:[{path,content,expected_sha256?}]}; "
"mcp_release payload: {files?:[patch entries],imports?:[{source,path,expected_source_sha256,"
"expected_target_sha256?}],services,checks?,message,paths?,build?,openwebui_sync?,hermes_sync?,"
"create_recovery?,recovery_label?}. imports copies already reviewed UTF-8 staging files by exact SHA "
"from an approved staging root, so never reproduce a long staged source file in a payload. It applies "
"drift-protected patches/imports, runs checks, "
"deploys only named MCP services, syncs OpenWebUI, publishes only selected paths and creates recovery. "
"Use mcp_release instead of manually chaining all those operations. run_checks: "
"{checks:[operator-tests,openwebui-filter-tests,platform-verify,compose-main,compose-mcp]}; "
"compose_deploy: {compose_file,services,build}; container_action: {action,containers}; "
"openwebui_sync: {}; "
"git_publish: {message,paths:[exact changed repository paths]}; model_download: {url,destination,sha256?}; benchmark: "
"{script,arguments}; recovery: {label}."
"Apply one durable change that the user has requested. Operations: patch_update, "
"file_update, mcp_release, run_checks, compose_deploy, container_action, "
"openwebui_sync, git_publish, model_download, benchmark, recovery. Use a small "
"patch for edits and file_update only for a new or intentionally replaced file. "
"mcp_release can perform the complete MCP build/test/deploy/publish workflow."
),
"inputSchema": {
"type": "object",
"properties": {
"operation": {"type": "string", "enum": ["patch_update", "file_update", "mcp_release", "run_checks", "compose_deploy", "container_action", "openwebui_sync", "git_publish", "model_download", "benchmark", "recovery"]},
"operation": {
"type": "string",
"enum": ["patch_update", "file_update", "mcp_release", "run_checks", "compose_deploy", "container_action", "openwebui_sync", "git_publish", "model_download", "benchmark", "recovery"],
},
"payload": {"type": "object"},
},
"required": ["operation", "payload"], "additionalProperties": False,
},
},
{
"name": "athena_operator_execute",
"description": (
"EXECUTE exactly one previously prepared Athena operation. Call only after the user "
"approved the exact preview in a later message and supplied the exact confirmation. "
"Tickets expire, are content-bound and single-use. Long downloads, benchmarks and "
"recovery work return a job id. This tool cannot alter SSH, networking, WireGuard, "
"firewall, boot, kernel, drivers, partitions, mounts, shutdown or reboot."
),
"inputSchema": {
"type": "object",
"properties": {
"ticket": {"type": "string", "pattern": "^[0-9a-f]{32}$"},
"confirmation": {"type": "string", "pattern": "^EXECUTE [0-9a-f]{32}$"},
},
"required": ["ticket", "confirmation"], "additionalProperties": False,
"required": ["operation", "payload"],
"additionalProperties": False,
},
},
{
"name": "athena_operator_job",
"description": "Poll one asynchronous model download, benchmark or recovery job. Do not start duplicate jobs while it is running.",
"inputSchema": {"type": "object", "properties": {"job_id": {"type": "string", "pattern": "^[0-9a-f]{32}$"}}, "required": ["job_id"], "additionalProperties": False},
"description": "Poll one asynchronous change returned by athena_operator_change. Do not start a duplicate job.",
"inputSchema": {
"type": "object",
"properties": {"job_id": {"type": "string", "pattern": "^[0-9a-f]{32}$"}},
"required": ["job_id"],
"additionalProperties": False,
},
},
]
@@ -143,7 +115,7 @@ TOOLS = [
def request(action: str, arguments: dict[str, Any]) -> dict[str, Any]:
payload = json.dumps({"action": action, "arguments": arguments}, ensure_ascii=False, separators=(",", ":")).encode() + b"\n"
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as client:
client.settimeout(20)
client.settimeout(3700 if action == "change" else 30)
client.connect(SOCKET_PATH)
client.sendall(payload)
chunks = bytearray()
@@ -163,16 +135,16 @@ def request(action: str, arguments: dict[str, Any]) -> dict[str, Any]:
def call(name: str, arguments: dict[str, Any]) -> dict[str, Any]:
mapping = {
"athena_operator_inspect": "inspect",
"athena_operator_read_source": "read_source",
"athena_operator_search_source": "search_source",
"athena_operator_read_source": "read_source",
"athena_operator_terminal": "terminal",
"athena_operator_prepare": "prepare",
"athena_operator_execute": "execute",
"athena_operator_change": "change",
"athena_operator_job": "job",
}
if name not in mapping:
raise ValueError("unknown tool")
return request(mapping[name], arguments)
action = mapping.get(name)
if action is None:
return {"ok": False, "error": "unknown tool", "retry": False}
return request(action, arguments)
def emit(request_id: Any, result: Any = None, error: dict[str, Any] | None = None) -> None:
@@ -185,14 +157,22 @@ def emit(request_id: Any, result: Any = None, error: dict[str, Any] | None = Non
def handle(message: dict[str, Any]) -> None:
method, request_id = message.get("method"), message.get("id")
if method == "initialize":
emit(request_id, {"protocolVersion": message.get("params", {}).get("protocolVersion", "2024-11-05"), "capabilities": {"tools": {"listChanged": False}}, "serverInfo": {"name": "mike-ai-athena-operator", "version": VERSION}})
emit(request_id, {
"protocolVersion": message.get("params", {}).get("protocolVersion", "2024-11-05"),
"capabilities": {"tools": {"listChanged": False}},
"serverInfo": {"name": "mike-ai-athena-operator", "version": VERSION},
})
elif method == "tools/list":
emit(request_id, {"tools": TOOLS})
elif method == "tools/call":
params = message.get("params", {})
params = message.get("params") or {}
try:
value = call(str(params.get("name", "")), params.get("arguments") or {})
emit(request_id, {"content": [{"type": "text", "text": json.dumps(value, ensure_ascii=False, separators=(",", ":"))}], "structuredContent": value, "isError": False})
emit(request_id, {
"content": [{"type": "text", "text": json.dumps(value, ensure_ascii=False, separators=(",", ":"))}],
"structuredContent": value,
"isError": False,
})
except Exception as exc:
emit(request_id, {"content": [{"type": "text", "text": f"ERROR: {exc}"}], "isError": True})
elif request_id is not None:
@@ -202,9 +182,11 @@ def handle(message: dict[str, Any]) -> None:
def main() -> None:
for line in sys.stdin:
try:
if line.strip(): handle(json.loads(line))
if line.strip():
handle(json.loads(line))
except Exception as exc:
sys.stderr.write(f"MCP input error: {exc}\n"); sys.stderr.flush()
sys.stderr.write(f"MCP input error: {exc}\n")
sys.stderr.flush()
if __name__ == "__main__":