Simplify Athena stack and recovery

This commit is contained in:
Mikei386
2026-08-25 22:27:26 +02:00
parent c4851305d1
commit 069da8b4f0
70 changed files with 887 additions and 5806 deletions
+71
View File
@@ -0,0 +1,71 @@
#!/usr/bin/env python3
"""Tests for the single declarative MCP client registry."""
from __future__ import annotations
import importlib.util
import json
import sqlite3
import tempfile
import unittest
from pathlib import Path
ROOT = Path(__file__).parents[1]
SOURCE = ROOT / "platform/mcp/sync-clients.py"
def load_module():
spec = importlib.util.spec_from_file_location("sync_clients", SOURCE)
module = importlib.util.module_from_spec(spec)
assert spec.loader
spec.loader.exec_module(module)
return module
class RegistryTests(unittest.TestCase):
def setUp(self):
self.module = load_module()
self.temp = tempfile.TemporaryDirectory()
self.root = Path(self.temp.name)
self.registry = self.root / "registry.json"
self.registry.write_text(json.dumps({"version": 1, "servers": [{
"id": "one", "name": "One", "description": "Test", "url": "http://one/mcp",
"clients": ["hermes", "openwebui"], "timeout": 123,
}]}))
def tearDown(self):
self.temp.cleanup()
def test_same_registry_generates_both_clients(self):
items = self.module.active(self.registry, "hermes")
block = self.module.hermes_block(items)
self.assertIn("one:", block)
db = self.root / "webui.db"
con = sqlite3.connect(db)
con.execute("create table config (key text primary key, value text, updated_at integer)")
con.commit(); con.close()
self.module.update_openwebui(db, self.module.active(self.registry, "openwebui"))
con = sqlite3.connect(db)
value = json.loads(con.execute("select value from config where key='tool_server.connections'").fetchone()[0])
con.close()
self.assertEqual(value[0]["info"]["id"], "one")
def test_old_platform_context_registration_is_removed(self):
db = self.root / "webui.db"
con = sqlite3.connect(db)
con.execute("create table config (key text primary key, value text, updated_at integer)")
con.execute("insert into config values (?,?,?)", ("tool_server.connections", json.dumps([
{"info": {"id": "athena-platform"}, "url": "http://old/mcp"},
{"info": {"id": "unmanaged"}, "url": "http://keep/mcp"},
]), 0))
con.commit(); con.close()
self.module.update_openwebui(db, self.module.active(self.registry, "openwebui"))
con = sqlite3.connect(db)
ids = [item["info"]["id"] for item in json.loads(con.execute("select value from config where key='tool_server.connections'").fetchone()[0])]
con.close()
self.assertEqual(ids, ["unmanaged", "one"])
if __name__ == "__main__":
unittest.main()
+2 -2
View File
@@ -361,7 +361,7 @@ class AutoToolSelectorTests(unittest.IsolatedAsyncioTestCase):
result = await self._select(
"Wie ist der KI-Host Athena aufgebaut und wo liegt der Recovery-Koffer?"
)
self.assertEqual(result["tool_ids"], ["server:mcp:athena-platform"])
self.assertEqual(result["tool_ids"], ["server:mcp:athena-operator-local"])
async def test_athena_operator_is_selected_for_platform_work(self):
result = await self._select(
@@ -371,7 +371,7 @@ class AutoToolSelectorTests(unittest.IsolatedAsyncioTestCase):
result["tool_ids"], ["server:mcp:athena-operator-local"]
)
async def test_mcp_build_from_github_gets_source_and_platform_context(self):
async def test_mcp_build_from_github_gets_source_and_operator(self):
result = await self._select(
"Ich möchte hierfür einen MCP bauen: https://github.com/foo/bar"
)
-61
View File
@@ -1,61 +0,0 @@
#!/usr/bin/env python3
import importlib.util
import json
import os
import tempfile
from pathlib import Path
def load_module(root: Path, runtime: Path):
os.environ.update({
"ATHENA_REPO_ROOT": str(root),
"ATHENA_RUNTIME_FILE": str(runtime),
})
source = Path(__file__).parents[1] / "platform/mcp/platform_context_mcp.py"
spec = importlib.util.spec_from_file_location("platform_context_mcp_test", source)
module = importlib.util.module_from_spec(spec)
assert spec.loader
spec.loader.exec_module(module)
return module
def main():
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp) / "repo"
runtime = Path(tmp) / "runtime.json"
(root / "docs").mkdir(parents=True)
(root / "config").mkdir(parents=True)
(root / "ATHENA.md").write_text("# Athena\nOne short source of truth.\n")
(root / "docs/OPERATIONS.md").write_text("# Operations\nRecovery detail.\n")
(root / "config/service-catalog.json").write_text(json.dumps({
"services": [{"id": "test", "name": "Test", "address": "127.0.0.1", "port": 9, "protocol": "tcp"}],
}))
runtime.write_text(json.dumps({
"generated_at": "2100-01-01T00:00:00Z", "source_commit": "abc",
"containers": [{"name": "mike-ai-test", "status": "Up"}],
"active_inference_profiles": ["fast"], "gpus": [],
}))
m = load_module(root, runtime)
assert len(m.TOOLS) == 5
assert m.overview()["source"] == "ATHENA.md"
assert m.current_state()["active_inference_profiles"] == ["fast"]
assert m.external_services()["services"][0]["id"] == "test"
assert m.search_reference({"query": "Recovery"})["matches"]
assert "Operations" in m.read_reference({"path": "docs/OPERATIONS.md"})["content"]
missing = m.read_reference({"path": "docs/MISSING.md"})
assert missing["ok"] is False and missing["retry"] is False
blocked = m.read_reference({"path": "config/secret.env"})
assert blocked["ok"] is False and blocked["retry"] is False
for tool in m.TOOLS:
for prop in tool["inputSchema"].get("properties", {}).values():
pattern = prop.get("pattern")
if pattern:
assert pattern.startswith("^") and pattern.endswith("$")
print("PLATFORM_CONTEXT_MCP_TEST_OK")
if __name__ == "__main__":
main()
+75
View File
@@ -0,0 +1,75 @@
#!/usr/bin/env python3
"""Focused offline tests for the model-oriented Radarr overlay."""
from __future__ import annotations
import importlib.util
import sys
import types
import unittest
from pathlib import Path
SOURCE = Path(__file__).parents[1] / "platform/mcp/patches/mcp_radarr.py"
def load_module():
utilities = types.ModuleType("agent_utilities.mcp_utilities")
utilities.dispatch = lambda *args, **kwargs: None
utilities.public_actions = lambda client: client.actions
utilities.run_blocking = lambda *args, **kwargs: None
sys.modules["agent_utilities"] = types.ModuleType("agent_utilities")
sys.modules["agent_utilities.mcp_utilities"] = utilities
fastmcp = types.ModuleType("fastmcp")
fastmcp.FastMCP = object
sys.modules["fastmcp"] = fastmcp
pydantic = types.ModuleType("pydantic")
pydantic.Field = lambda *args, **kwargs: kwargs.get("default")
sys.modules["pydantic"] = pydantic
auth = types.ModuleType("arr_mcp.auth")
auth.get_radarr_client = lambda: None
sys.modules["arr_mcp"] = types.ModuleType("arr_mcp")
sys.modules["arr_mcp.auth"] = auth
spec = importlib.util.spec_from_file_location("radarr_patch", SOURCE)
module = importlib.util.module_from_spec(spec)
assert spec.loader
spec.loader.exec_module(module)
return module
class RadarrPatchTests(unittest.TestCase):
def setUp(self):
self.module = load_module()
self.movies = [{
"id": 12, "title": "Example", "year": 2024, "hasFile": True,
"alternateTitles": [{"title": "large unwanted block"}],
"movieFile": {
"id": 44, "relativePath": "Example.mkv", "size": 2147483648,
"quality": {"quality": {"name": "Bluray-1080p"}},
"mediaInfo": {
"videoCodec": "x264", "resolution": "1920x1080",
"videoBitDepth": 8, "audioCodec": "EAC3",
"audioLanguages": "ger/eng", "subtitles": "ger",
},
},
}]
def test_inventory_is_compact_and_alias_aware(self):
result = self.module._compact_inventory(self.movies, codecs="h264")
self.assertEqual(result["totalMatched"], 1)
self.assertEqual(result["movies"][0]["videoCodec"], "x264")
self.assertEqual(result["movies"][0]["sizeGiB"], 2.0)
self.assertNotIn("alternateTitles", result["movies"][0])
def test_filter_and_pagination_return_valid_bounded_data(self):
result = self.module._compact_inventory(self.movies * 5, query="example", offset=1, limit=2)
self.assertEqual(result["returned"], 2)
self.assertTrue(result["hasMore"])
def test_internal_transport_and_power_actions_are_hidden(self):
client = types.SimpleNamespace(actions=["get_movie", "request", "post_system_shutdown", "get_queue"])
self.assertEqual(self.module._safe_actions(client), ["get_movie", "get_queue"])
if __name__ == "__main__":
unittest.main()
-2
View File
@@ -14,8 +14,6 @@ verify() {
docker exec "$OWUI_CONTAINER" python3 "$VERIFY_REMOTE" "$@"
}
verify http://mike-ai-mcp-platform-context:8000/mcp \
--max-tools 12 --max-schema-chars 12000
verify http://mike-ai-mcp-athena-operator:8000/mcp \
--max-tools 8 --max-schema-chars 12000
verify http://tinysearch:8000/mcp \