Rhodawk Mythos Agent
mythos: ascend to Mythos-level — multi-agent + probabilistic + advanced tooling + RL + MCP suite + FastAPI
14b1bbe
Raw
History Blame Contribute Delete
2.19 kB
"""
LoRA / QLoRA adapter manager.
Wraps the existing ``lora_scheduler`` module and adds Mythos-specific
versioning + A/B testing semantics. Adapters are pinned per (cwe, target
language) so the orchestrator can ship a specialised Tier-2 weight set per
campaign class.
"""
from __future__ import annotations
import json
import os
import time
from typing import Any
_ADAPTERS_INDEX = os.getenv("MYTHOS_ADAPTER_INDEX", "/data/mythos/adapters/index.json")
class LoRAAdapterManager:
def __init__(self):
self.index: dict[str, dict[str, Any]] = {}
self._load()
def register(self, name: str, *, cwe: str, language: str, base_model: str,
weight_path: str, metrics: dict[str, float] | None = None) -> str:
entry = {
"name": name, "cwe": cwe, "language": language, "base_model": base_model,
"weight_path": weight_path, "metrics": metrics or {},
"version": int(time.time()),
}
self.index.setdefault(name, {})["latest"] = entry
self.index[name].setdefault("history", []).append(entry)
self._save()
return f"{name}@{entry['version']}"
def select(self, *, cwe: str, language: str) -> dict[str, Any] | None:
for name, body in self.index.items():
latest = body.get("latest", {})
if latest.get("cwe") == cwe and latest.get("language") == language:
return latest
return None
def rollback(self, name: str) -> dict[str, Any] | None:
body = self.index.get(name, {})
history = body.get("history", [])
if len(history) < 2:
return None
body["latest"] = history[-2]
self._save()
return body["latest"]
def _load(self) -> None:
try:
with open(_ADAPTERS_INDEX) as fh:
self.index = json.load(fh)
except Exception: # noqa: BLE001
pass
def _save(self) -> None:
try:
os.makedirs(os.path.dirname(_ADAPTERS_INDEX), exist_ok=True)
with open(_ADAPTERS_INDEX, "w") as fh:
json.dump(self.index, fh, indent=2)
except OSError:
pass