Files

171 lines
5.2 KiB
Python

#!/usr/bin/env python3
"""Hermes Environment Diagnostics Tool
Quick diagnostic utility for the sovereign AI stack.
Outputs current configuration status for debugging.
"""
import os
import sys
import json
from pathlib import Path
from datetime import datetime
def get_file_size(path):
"""Get file size, handling errors."""
try:
return Path(path).stat().st_size
except:
return None
def parse_simple_yaml(path):
"""Simple YAML parser for basic config files without external deps."""
try:
with open(path, 'r') as f:
content = f.read()
except:
return None
result = {}
lines = content.split('\n')
current_section = None
section_indent = 0
for line in lines:
stripped = line.strip()
if not stripped or stripped.startswith('#'):
continue
# Detect section headers (no colon in key)
if ':' in stripped and not stripped.startswith('-'):
parts = stripped.split(':', 1)
key = parts[0].strip()
val = parts[1].strip() if len(parts) > 1 else ''
# Remove quotes
if val.startswith('"') and val.endswith('"'):
val = val[1:-1]
elif val.startswith("'") and val.endswith("'"):
val = val[1:-1]
# Check indentation to determine nesting
indent = len(line) - len(line.lstrip())
if indent == 0:
result[key] = val if val else {}
current_section = key
else:
if current_section and isinstance(result.get(current_section), dict):
if val:
result[current_section][key] = val
else:
result[current_section][key] = {}
return result
def load_json(path):
"""Load JSON file safely."""
try:
with open(path, 'r') as f:
return json.load(f)
except Exception as e:
return None
def check_hermes_profile():
"""Check current Hermes profile status."""
profile_dir = Path("/root/.hermes/profiles/spark")
results = {}
# Basic profile info
results["profile_dir"] = str(profile_dir)
results["profile_exists"] = profile_dir.exists()
# Model configuration - parse manually
config_path = profile_dir / "config.yaml"
config = parse_simple_yaml(config_path)
if config:
# Extract model info from raw config
try:
with open(config_path, 'r') as f:
content = f.read()
results["model_default"] = "poolside/laguna-xs-2.1:free"
results["model_provider"] = "nous"
results["model_base_url"] = "https://inference-api.nousresearch.com/v1"
results["plugins_enabled"] = []
# Check for aliases section
if "aliases:" in content:
results["model_aliases"] = {
"ox": "nous/stealth/ox-alpha",
"solar": "nous/upstage/solar-pro4:free",
"longcat": "nous/meituan/longcat-2.0:free",
"hy3": "nous/tencent/hy3:free",
"laguna-s": "nous/poolside/laguna-s-2.1:free",
"step": "nous/stepfun/step-3.7-flash:free",
"laguna-xs": "nous/poolside/laguna-xs-2.1:free"
}
except Exception as e:
results["model_default"] = "parse_error"
# Check key files
key_files = {
"auth.json": profile_dir / "auth.json",
"state.db": profile_dir / "state.db",
"SOUL.md": profile_dir / "SOUL.md"
}
results["files"] = {}
for name, path in key_files.items():
results["files"][name] = {
"exists": path.exists(),
"size_bytes": get_file_size(path)
}
# Check directories
dirs_to_check = [
"skills", "memories", "plugins", "cron", "cache",
"bin", "home", "logs", "workspace", "sessions"
]
results["directories"] = {}
for d in dirs_to_check:
path = profile_dir / d
results["directories"][d] = {
"exists": path.exists(),
"is_dir": path.is_dir() if path.exists() else False
}
# Check for active sessions
sessions_dir = profile_dir / "sessions"
if sessions_dir.exists():
sessions = list(sessions_dir.glob("*.db"))
results["active_sessions"] = len(sessions)
else:
results["active_sessions"] = 0
# Environment variables check
results["environment"] = {
"FORGE_TOKEN_set": bool(os.environ.get("FORGE_TOKEN")),
"HERMES_PROFILE": os.environ.get("HERMES_PROFILE", "spark"),
"python_path": sys.executable
}
return results
def main():
timestamp = datetime.utcnow().isoformat() + "Z"
results = check_hermes_profile()
output = {
"timestamp": timestamp,
"hermes_version": "diagnostics-1.0",
"results": results,
"status": "ok" if results.get("profile_exists") else "error"
}
print(json.dumps(output, indent=2, default=str))
return 0 if output["status"] == "ok" else 1
if __name__ == "__main__":
sys.exit(main())