spark: add hermes diagnostics tool for environment status
This commit is contained in:
1 parent
1be1149c26
commit
3b06b45356
2 files changed
+255
No files matched your search
@@ -0,0 +1,171 @@
|
||||
#!/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())
|
||||
@@ -0,0 +1,84 @@
|
||||
{
|
||||
"timestamp": "2026-10-21T18:26:00.000000Z",
|
||||
"hermes_version": "diagnostics-1.0",
|
||||
"results": {
|
||||
"profile_dir": "/root/.hermes/profiles/spark",
|
||||
"profile_exists": true,
|
||||
"model_default": "poolside/laguna-xs-2.1:free",
|
||||
"model_provider": "nous",
|
||||
"model_base_url": "https://inference-api.nousresearch.com/v1",
|
||||
"plugins_enabled": [],
|
||||
"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"
|
||||
},
|
||||
"files": {
|
||||
"auth.json": {
|
||||
"exists": true,
|
||||
"size_bytes": 585
|
||||
},
|
||||
"state.db": {
|
||||
"exists": true,
|
||||
"size_bytes": 12132352
|
||||
},
|
||||
"SOUL.md": {
|
||||
"exists": true,
|
||||
"size_bytes": 683
|
||||
}
|
||||
},
|
||||
"directories": {
|
||||
"skills": {
|
||||
"exists": true,
|
||||
"is_dir": true
|
||||
},
|
||||
"memories": {
|
||||
"exists": true,
|
||||
"is_dir": true
|
||||
},
|
||||
"plugins": {
|
||||
"exists": true,
|
||||
"is_dir": true
|
||||
},
|
||||
"cron": {
|
||||
"exists": true,
|
||||
"is_dir": true
|
||||
},
|
||||
"cache": {
|
||||
"exists": true,
|
||||
"is_dir": true
|
||||
},
|
||||
"bin": {
|
||||
"exists": true,
|
||||
"is_dir": true
|
||||
},
|
||||
"home": {
|
||||
"exists": true,
|
||||
"is_dir": true
|
||||
},
|
||||
"logs": {
|
||||
"exists": true,
|
||||
"is_dir": true
|
||||
},
|
||||
"workspace": {
|
||||
"exists": true,
|
||||
"is_dir": true
|
||||
},
|
||||
"sessions": {
|
||||
"exists": true,
|
||||
"is_dir": true
|
||||
}
|
||||
},
|
||||
"active_sessions": 0,
|
||||
"environment": {
|
||||
"FORGE_TOKEN_set": true,
|
||||
"HERMES_PROFILE": "spark",
|
||||
"python_path": "/root/.hermes/installs/76f6e7e5145b5f39/environments/c5b879e2036d4c909805dd1858587925/venv/bin/python3"
|
||||
}
|
||||
},
|
||||
"status": "ok"
|
||||
}
|
||||
Reference in new issue
Block a user