Rhodawk Mythos Agent
mythos: ascend to Mythos-level — multi-agent + probabilistic + advanced tooling + RL + MCP suite + FastAPI
14b1bbe
Raw
History Blame Contribute Delete
2.36 kB
"""Thin MLflow tracker — falls back to a JSONL log when MLflow is absent."""
from __future__ import annotations
import json
import os
import time
import uuid
from typing import Any
try: # pragma: no cover
import mlflow # type: ignore
_MLFLOW = True
except Exception: # noqa: BLE001
_MLFLOW = False
_FALLBACK_LOG = os.getenv("MYTHOS_MLFLOW_FALLBACK", "/data/mythos/mlflow_fallback.jsonl")
class MLflowTracker:
def __init__(self, experiment: str = "mythos"):
self.experiment = experiment
if _MLFLOW:
try:
mlflow.set_experiment(experiment)
except Exception: # noqa: BLE001
pass
def start_run(self, tags: dict[str, str] | None = None) -> str:
if _MLFLOW:
try:
run = mlflow.start_run(tags=tags or {})
return run.info.run_id
except Exception: # noqa: BLE001
pass
run_id = uuid.uuid4().hex
self._jsonl({"event": "start", "run_id": run_id, "tags": tags or {},
"experiment": self.experiment, "ts": time.time()})
return run_id
def log_iteration(self, run_id: str, iteration: dict[str, Any]) -> None:
if _MLFLOW:
try:
mlflow.log_metric("hypotheses",
len(iteration.get("plan", {}).get("hypotheses", [])),
step=iteration.get("n", 0))
mlflow.log_metric("crashes",
iteration.get("refinement", {}).get("confirmed_count", 0),
step=iteration.get("n", 0))
except Exception: # noqa: BLE001
pass
self._jsonl({"event": "iter", "run_id": run_id, "iter": iteration})
def end_run(self, run_id: str) -> None:
if _MLFLOW:
try:
mlflow.end_run()
except Exception: # noqa: BLE001
pass
self._jsonl({"event": "end", "run_id": run_id, "ts": time.time()})
def _jsonl(self, payload: dict[str, Any]) -> None:
try:
os.makedirs(os.path.dirname(_FALLBACK_LOG), exist_ok=True)
with open(_FALLBACK_LOG, "a") as fh:
fh.write(json.dumps(payload, default=str) + "\n")
except OSError:
pass