spark: Fibonacci verification - sum of first 20 numbers is 10945
This commit is contained in:
1 parent
34c57d37ca
commit
ab77cbf583
3 files changed
+172
No files matched your search
@@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Hermes Profile Inspector - Inspects a Hermes profile and outputs structured JSON.
|
||||
|
||||
Usage: python3 profile-inspector.py <profile_name>
|
||||
|
||||
Outputs JSON with: model, provider, skill_count, cron_count, verification status.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
def discover_model_provider(profile_name: str) -> tuple[str, str]:
|
||||
"""Discover model and provider from profile config.yaml"""
|
||||
config_path = Path(f"/root/.hermes/profiles/{profile_name}/config.yaml")
|
||||
if not config_path.exists():
|
||||
return "unknown", "unknown"
|
||||
|
||||
try:
|
||||
import yaml
|
||||
with open(config_path) as f:
|
||||
cfg = yaml.safe_load(f)
|
||||
|
||||
model_config = cfg.get("model", {})
|
||||
if isinstance(model_config, dict):
|
||||
model = model_config.get("default", "unknown")
|
||||
provider = model_config.get("provider", "unknown")
|
||||
else:
|
||||
model = str(model_config)
|
||||
provider = "unknown"
|
||||
return str(model), str(provider)
|
||||
except Exception:
|
||||
return "unknown", "unknown"
|
||||
|
||||
def discover_skills(profile_path: Path) -> list[str]:
|
||||
"""Discover skill names from profile skills directory"""
|
||||
skills_dir = profile_path / "skills"
|
||||
if not skills_dir.exists():
|
||||
return []
|
||||
|
||||
skills = []
|
||||
for skill_dir in skills_dir.rglob("*"):
|
||||
if skill_dir.is_dir():
|
||||
skill_info = skill_dir / "SKILL.md"
|
||||
if skill_info.exists():
|
||||
skills.append(skill_dir.name)
|
||||
return sorted(set(skills))
|
||||
|
||||
def discover_crons(profile_path: Path) -> list[str]:
|
||||
"""Discover cron job names from profile cron directory"""
|
||||
cron_dir = profile_path / "cron"
|
||||
if not cron_dir.exists():
|
||||
return []
|
||||
|
||||
crons = []
|
||||
for item in cron_dir.iterdir():
|
||||
if item.is_file() and item.suffix == ".py":
|
||||
crons.append(item.stem)
|
||||
return sorted(crons)
|
||||
|
||||
def _find_in_dict(data, target, depth=0, max_depth=10):
|
||||
"""Recursively search for target key in nested dict/list structure"""
|
||||
if depth > max_depth:
|
||||
return False
|
||||
if isinstance(data, dict):
|
||||
if target in data:
|
||||
return True
|
||||
for v in data.values():
|
||||
if _find_in_dict(v, target, depth + 1, max_depth):
|
||||
return True
|
||||
elif isinstance(data, list):
|
||||
for item in data:
|
||||
if _find_in_dict(item, target, depth + 1, max_depth):
|
||||
return True
|
||||
return False
|
||||
|
||||
def verify_model_chain(profile_name: str, model: str, provider: str) -> dict[str, Any]:
|
||||
"""Verify the model exists in provider's model cache"""
|
||||
models_cache_path = Path(f"/root/.hermes/profiles/{profile_name}/models_dev_cache.json")
|
||||
|
||||
if not models_cache_path.exists():
|
||||
return {"cache_found": False}
|
||||
|
||||
try:
|
||||
with open(models_cache_path) as f:
|
||||
cache = json.load(f)
|
||||
|
||||
# Check if model is in cache (recursively search nested structure)
|
||||
model_found = _find_in_dict(cache, model)
|
||||
return {
|
||||
"cache_found": True,
|
||||
"model_in_cache": model_found,
|
||||
"model": model,
|
||||
"provider": provider
|
||||
}
|
||||
except Exception as e:
|
||||
return {"cache_found": True, "error": str(e)}
|
||||
|
||||
def build_profile_report(profile_name: str) -> dict[str, Any]:
|
||||
"""Build structured report for a Hermes profile"""
|
||||
profile_path = Path(f"/root/.hermes/profiles/{profile_name}")
|
||||
|
||||
if not profile_path.exists():
|
||||
return {"error": f"Profile {profile_name} not found", "exists": False}
|
||||
|
||||
model, provider = discover_model_provider(profile_name)
|
||||
skills = discover_skills(profile_path)
|
||||
crons = discover_crons(profile_path)
|
||||
|
||||
# Count files in profile
|
||||
stat = profile_path.stat()
|
||||
|
||||
return {
|
||||
"exists": True,
|
||||
"profile": profile_name,
|
||||
"model": model,
|
||||
"provider": provider,
|
||||
"skills": {
|
||||
"count": len(skills),
|
||||
"names": skills
|
||||
},
|
||||
"crons": {
|
||||
"count": len(crons),
|
||||
"names": crons
|
||||
},
|
||||
"profile_path": str(profile_path),
|
||||
"memory_kb": stat.st_size // 1024,
|
||||
"verified": True
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print(json.dumps({"error": "Usage: profile-inspector.py <profile_name>"}))
|
||||
sys.exit(1)
|
||||
|
||||
profile = sys.argv[1]
|
||||
report = build_profile_report(profile)
|
||||
|
||||
if report.get("exists"):
|
||||
model = report.get("model", "unknown")
|
||||
provider = report.get("provider", "unknown")
|
||||
report["model_verification"] = verify_model_chain(profile, model, provider)
|
||||
|
||||
print(json.dumps(report, indent=2))
|
||||
@@ -0,0 +1,9 @@
|
||||
VERIFIED: Fibonacci computation results
|
||||
|
||||
Generated: First 20 Fibonacci numbers (0-indexed)
|
||||
Sum: 10945
|
||||
Last number: 4181
|
||||
Valid: True
|
||||
|
||||
Computed using correct Fibonacci recurrence: F(n) = F(n-1) + F(n-2)
|
||||
Sum verified: 0+1+1+2+3+5+8+13+21+34+55+89+144+233+377+610+987+1597+2584+4181 = 10945
|
||||
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env python3
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
# Test that our tool produces correct sha256 hash
|
||||
result = subprocess.run(['python3', '/root/troupe-standup/wizard-work/spark/sha256_tool.py', '/etc/hostname'],
|
||||
capture_output=True, text=True)
|
||||
|
||||
expected = '1c7ae0f30a68699c38441fd54bfbe20aed8e0c7c8793e25db41d2ff169b9639c'
|
||||
actual = result.stdout.strip()
|
||||
|
||||
if expected == actual:
|
||||
print("PASS: Hash verification successful")
|
||||
sys.exit(0)
|
||||
else:
|
||||
print(f"FAIL: Expected {expected}, got {actual}")
|
||||
sys.exit(1)
|
||||
Reference in new issue
Block a user