Spaces:
Running
Running
File size: 6,258 Bytes
020c94b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | #!/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))
|