76 lines
4.6 KiB
Python
76 lines
4.6 KiB
Python
#!/usr/bin/env python3
|
|
"""WEVIA AGENT FACTORY v1.0 — Analyzes architecture + Creates missing agents
|
|
Scans the system, identifies gaps, proposes + creates agent skills. Cron */12h."""
|
|
import json, os, subprocess, urllib.request, ssl, glob
|
|
from datetime import datetime
|
|
|
|
ssl._create_default_https_context = ssl._create_unverified_context
|
|
REPORT = "/var/www/html/api/agent-factory-report.json"
|
|
SKILLS_DIR = "/opt/deer-flow/skills/weval"
|
|
|
|
def log(m): print(f"[{datetime.now().strftime('%H:%M:%S')}] {m}")
|
|
def sh(c): return subprocess.run(c, shell=True, capture_output=True, text=True, timeout=10).stdout.strip()
|
|
|
|
def main():
|
|
log("=== AGENT FACTORY v1.0 ===")
|
|
report = {"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M"), "analysis": {}, "created": [], "proposed": []}
|
|
|
|
# 1. Scan existing agents/skills
|
|
log("1. Scan existing")
|
|
existing_skills = [os.path.basename(d) for d in glob.glob(f"{SKILLS_DIR}/*/")]
|
|
report["analysis"]["existing_skills"] = len(existing_skills)
|
|
|
|
# 2. Scan what the system HAS but no agent covers
|
|
log("2. Gap analysis")
|
|
# Services that should have agents
|
|
expected_agents = {
|
|
"docker-monitor": {"need": "Monitor all Docker containers, restart if unhealthy", "check": "docker" in str(existing_skills)},
|
|
"disk-cleaner": {"need": "Auto-clean old logs, temp files when disk > 85%", "check": "disk" in str(existing_skills)},
|
|
"ssl-renewal": {"need": "Monitor SSL cert expiry, auto-renew with certbot", "check": "ssl" in str(existing_skills)},
|
|
"backup-agent": {"need": "GOLD backup all critical files daily", "check": "backup" in str(existing_skills)},
|
|
"github-sync": {"need": "Auto git push to GitHub every hour", "check": "github" in str(existing_skills)},
|
|
"dataset-grower": {"need": "Auto-grow training dataset from conversations", "check": "dataset" in str(existing_skills) or "autolearn" in str(existing_skills)},
|
|
"qdrant-optimizer": {"need": "Optimize Qdrant collections, remove duplicates", "check": "qdrant" in str(existing_skills)},
|
|
"cron-guardian": {"need": "Verify all crons run on schedule, restart if stuck", "check": "cron" in str(existing_skills) or "guard" in str(existing_skills)},
|
|
"api-health": {"need": "Health check all 15+ APIs every 5min", "check": "health" in str(existing_skills)},
|
|
"performance-agent": {"need": "Monitor response times, alert if degradation", "check": "performance" in str(existing_skills) or "perf" in str(existing_skills)},
|
|
"ethica-enricher": {"need": "Auto-enrich HCPs with missing emails/phones", "check": "ethica-enrich" in str(existing_skills)},
|
|
"wiki-pruner": {"need": "Remove outdated wiki entries, merge duplicates", "check": "wiki-prun" in str(existing_skills)},
|
|
"log-analyzer": {"need": "Analyze error logs, detect patterns, propose fixes", "check": "log" in str(existing_skills)},
|
|
"security-patrol": {"need": "Continuous security scan, detect new vulnerabilities", "check": "security" in str(existing_skills)},
|
|
"ux-tester": {"need": "Playwright visual regression on all pages daily", "check": "ux" in str(existing_skills) or "visual-test" in str(existing_skills)},
|
|
}
|
|
|
|
missing = []
|
|
for name, info in expected_agents.items():
|
|
if not info["check"]:
|
|
missing.append({"name": name, "need": info["need"]})
|
|
report["analysis"]["missing"] = len(missing)
|
|
report["proposed"] = missing
|
|
log(f"Missing agents: {len(missing)}/{len(expected_agents)}")
|
|
|
|
# 3. Auto-create missing agent skills
|
|
log("3. Creating missing agents")
|
|
for agent in missing:
|
|
skill_dir = f"{SKILLS_DIR}/{agent['name']}"
|
|
if not os.path.exists(skill_dir):
|
|
os.makedirs(skill_dir, exist_ok=True)
|
|
skill_md = f"# {agent['name']}\n\n## Purpose\n{agent['need']}\n\n## Type\nAutonomous agent - auto-created by Agent Factory\n\n## Created\n{datetime.now().isoformat()}\n"
|
|
with open(f"{skill_dir}/SKILL.md", "w") as f: f.write(skill_md)
|
|
report["created"].append(agent["name"])
|
|
log(f" CREATED: {agent['name']}")
|
|
else:
|
|
log(f" EXISTS: {agent['name']}")
|
|
|
|
# 4. Count final state
|
|
final_skills = len(glob.glob(f"{SKILLS_DIR}/*/"))
|
|
report["analysis"]["final_skills"] = final_skills
|
|
report["analysis"]["new_skills"] = final_skills - len(existing_skills)
|
|
|
|
# SAVE
|
|
with open(REPORT, "w") as f: json.dump(report, f, indent=2, ensure_ascii=False)
|
|
log(f"Report saved. Created {len(report['created'])} new agents. Total skills: {final_skills}")
|
|
|
|
try: main()
|
|
except Exception as e: print(f"CRASH: {e}"); import traceback; traceback.print_exc()
|