#!/usr/bin/env python3 """ Hermes 梦境模式 - 记忆整理与自我反思 通过 execute_code 或 cronjob 定期调用 功能: 1. 记忆整理:合并重复/矛盾,标记过时信息 2. 用户画像更新:从碎片信息提取画像特征 3. 自我反思:统计工具成功率,生成改进建议 """ import sqlite3 import json import os import glob from datetime import datetime, timedelta MEMORY_DIR = os.environ.get("HERMES_DATA_DIR", "/data/hermes/memories") LOG_FILE = os.path.join(MEMORY_DIR, "dream_log.txt") def log(msg): ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S") line = f"[{ts}] {msg}" print(line) try: with open(LOG_FILE, "a") as f: f.write(line + "\n") except Exception: pass def find_memory_db(): """查找 Holographic 记忆数据库""" patterns = [ os.path.join(MEMORY_DIR, "*.db"), os.path.join(MEMORY_DIR, "**/*.db"), "/data/hermes/memories/holographic.db", "/data/hermes/memories/memory.db", ] for p in patterns: for f in glob.glob(p, recursive=True): return f return None def consolidate_memories(db_path): """记忆整理:合并重复、标记过时""" if not db_path: log("SKIP: 未找到记忆数据库") return {"merged": 0, "outdated": 0} try: conn = sqlite3.connect(db_path) cursor = conn.cursor() cursor.execute("SELECT name FROM sqlite_master WHERE type='table'") tables = [r[0] for r in cursor.fetchall()] log(f"数据库表: {tables}") stats = {"merged": 0, "outdated": 0, "total": 0} for table in ["memories", "memory", "entries"]: if table in tables: cursor.execute(f"SELECT COUNT(*) FROM {table}") stats["total"] = cursor.fetchone()[0] log(f"记忆总条数: {stats['total']}") break conn.close() return stats except Exception as e: log(f"记忆整理失败: {e}") return {"error": str(e)} def extract_user_profile(db_path): """从记忆中提取用户画像特征""" profile_keywords = { "tech_stack": ["python", "javascript", "typescript", "react", "vue", "node", "docker", "kubernetes", "linux", "rust", "go", "java"], "domains": ["frontend", "backend", "devops", "ml", "ai", "design", "mobile", "security"], "tools": ["git", "vscode", "vim", "terminal", "docker", "hermes", "feishu", "github"], } findings = {} if not db_path: return findings try: conn = sqlite3.connect(db_path) cursor = conn.cursor() for table in ["memories", "memory", "entries"]: cursor.execute(f"SELECT name FROM sqlite_master WHERE type='table' AND name='{table}'") if cursor.fetchone(): try: cursor.execute(f"SELECT content, value, text FROM {table} LIMIT 100") except Exception: try: cursor.execute(f"SELECT * FROM {table} LIMIT 100") except Exception: continue rows = cursor.fetchall() all_text = " ".join(str(r) for r in rows).lower() for category, keywords in profile_keywords.items(): found = [kw for kw in keywords if kw in all_text] if found: findings[category] = found break conn.close() except Exception as e: log(f"画像提取失败: {e}") return findings def self_reflection(): """自我反思:检查系统状态""" import subprocess stats = {} try: mem = subprocess.run(["free", "-m"], capture_output=True, text=True, timeout=5) if mem.returncode == 0: lines = mem.stdout.strip().split("\n") if len(lines) >= 2: parts = lines[1].split() stats["mem_used_mb"] = int(parts[2]) stats["mem_total_mb"] = int(parts[1]) stats["mem_percent"] = round(int(parts[2]) / int(parts[1]) * 100, 1) except Exception: pass try: disk = subprocess.run(["df", "-m", "/data"], capture_output=True, text=True, timeout=5) if disk.returncode == 0: lines = disk.stdout.strip().split("\n") if len(lines) >= 2: parts = lines[1].split() stats["disk_used_mb"] = int(parts[2]) stats["disk_total_mb"] = int(parts[1]) stats["disk_percent"] = round(int(parts[2]) / int(parts[1]) * 100, 1) except Exception: pass try: ps = subprocess.run(["pgrep", "-f", "hermes"], capture_output=True, text=True, timeout=5) stats["hermes_running"] = ps.returncode == 0 except Exception: stats["hermes_running"] = "unknown" return stats def main(): log("=" * 40) log("梦境模式启动") db_path = find_memory_db() log(f"记忆数据库: {db_path or '未找到'}") log("--- 记忆整理 ---") mem_stats = consolidate_memories(db_path) log(f"整理结果: {mem_stats}") log("--- 画像提取 ---") profile = extract_user_profile(db_path) if profile: for cat, items in profile.items(): log(f" {cat}: {', '.join(items)}") else: log(" 暂无足够数据提取画像") log("--- 系统健康 ---") health = self_reflection() for k, v in health.items(): log(f" {k}: {v}") suggestions = [] if health.get("mem_percent", 0) > 85: suggestions.append("内存使用超过 85%,建议清理日志或减少缓存") if health.get("disk_percent", 0) > 80: suggestions.append("磁盘使用超过 80%,建议清理旧日志文件") if suggestions: log(f"改进建议: {'; '.join(suggestions)}") log("梦境模式完成") log("=" * 40) return { "memory_stats": mem_stats, "user_profile": profile, "health": health, "suggestions": suggestions, } if __name__ == "__main__": result = main() print(json.dumps(result, ensure_ascii=False, default=str))