202 lines
7.0 KiB
Python
202 lines
7.0 KiB
Python
|
|
"""
|
||
|
|
铸渊工具链 · Gatekeeper + Git + HLDP 读写
|
||
|
|
光湖语言世界 · 铸渊 ICE-GL-ZY001 · D112
|
||
|
|
"""
|
||
|
|
|
||
|
|
import subprocess
|
||
|
|
import json
|
||
|
|
import os
|
||
|
|
import time
|
||
|
|
from typing import Optional
|
||
|
|
import requests
|
||
|
|
|
||
|
|
|
||
|
|
# === Gatekeeper 连接器 ===
|
||
|
|
|
||
|
|
class GatekeeperClient:
|
||
|
|
"""Gatekeeper HTTP 客户端 · 六服务器桥接"""
|
||
|
|
|
||
|
|
def __init__(self, base_url: str = None, token: str = None):
|
||
|
|
self.base_url = base_url or os.environ.get("GK_BASE_URL", "http://43.139.217.141:3910")
|
||
|
|
self.token = token or os.environ.get("GK_TOKEN", "")
|
||
|
|
self.session = requests.Session()
|
||
|
|
self.session.headers.update({
|
||
|
|
"Authorization": f"Bearer {self.token}",
|
||
|
|
"Content-Type": "application/json"
|
||
|
|
})
|
||
|
|
|
||
|
|
def ping(self) -> dict:
|
||
|
|
"""检测 Gatekeeper 存活"""
|
||
|
|
try:
|
||
|
|
r = self.session.get(f"{self.base_url}/ping", timeout=5)
|
||
|
|
return {"status": "alive", "data": r.json()}
|
||
|
|
except Exception as e:
|
||
|
|
return {"status": "down", "error": str(e)}
|
||
|
|
|
||
|
|
def exec(self, server: str, command: str, timeout: int = 30) -> dict:
|
||
|
|
"""在指定服务器上执行命令"""
|
||
|
|
try:
|
||
|
|
r = self.session.post(
|
||
|
|
f"{self.base_url}/exec",
|
||
|
|
json={"server": server, "command": command},
|
||
|
|
timeout=timeout)
|
||
|
|
return {"status": "ok", "data": r.json()}
|
||
|
|
except Exception as e:
|
||
|
|
return {"status": "error", "error": str(e)}
|
||
|
|
|
||
|
|
def check_all_servers(self) -> dict:
|
||
|
|
"""检测所有六台服务器状态"""
|
||
|
|
servers = ["BS-GZ-006", "BS-SG-001", "BS-SG-002", "BS-SG-003", "ZY-SG-006", "BS-SH-005"]
|
||
|
|
results = {}
|
||
|
|
for s in servers:
|
||
|
|
try:
|
||
|
|
r = self.session.post(
|
||
|
|
f"{self.base_url}/exec",
|
||
|
|
json={"server": s, "command": "uptime"},
|
||
|
|
timeout=10)
|
||
|
|
results[s] = "online" if r.status_code == 200 else "degraded"
|
||
|
|
except Exception:
|
||
|
|
results[s] = "offline"
|
||
|
|
return results
|
||
|
|
|
||
|
|
|
||
|
|
# === Git 工具 ===
|
||
|
|
|
||
|
|
class GitTools:
|
||
|
|
"""代码仓库操作工具"""
|
||
|
|
|
||
|
|
def __init__(self, repo_path: str = None):
|
||
|
|
self.repo_path = repo_path or os.environ.get("REPO_PATH", os.getcwd())
|
||
|
|
|
||
|
|
def status(self) -> dict:
|
||
|
|
"""获取仓库状态"""
|
||
|
|
r = subprocess.run(["git", "-C", self.repo_path, "status", "--short"],
|
||
|
|
capture_output=True, text=True, timeout=10)
|
||
|
|
files = [f for f in r.stdout.strip().split("\n") if f]
|
||
|
|
return {
|
||
|
|
"branch": self._current_branch(),
|
||
|
|
"changed_files": len(files),
|
||
|
|
"files": files[:20]
|
||
|
|
}
|
||
|
|
|
||
|
|
def log(self, n: int = 5) -> list[str]:
|
||
|
|
"""最近提交"""
|
||
|
|
r = subprocess.run(
|
||
|
|
["git", "-C", self.repo_path, "log", f"-{n}", "--oneline", "--no-decorate"],
|
||
|
|
capture_output=True, text=True, timeout=10)
|
||
|
|
return [l for l in r.stdout.strip().split("\n") if l]
|
||
|
|
|
||
|
|
def diff(self) -> str:
|
||
|
|
"""未暂存变更"""
|
||
|
|
r = subprocess.run(["git", "-C", self.repo_path, "diff"],
|
||
|
|
capture_output=True, text=True, timeout=10)
|
||
|
|
return r.stdout[:2000]
|
||
|
|
|
||
|
|
def commit_and_push(self, message: str, files: list[str] = None) -> dict:
|
||
|
|
"""提交并推送"""
|
||
|
|
try:
|
||
|
|
if files:
|
||
|
|
subprocess.run(["git", "-C", self.repo_path, "add"] + files,
|
||
|
|
capture_output=True, text=True, timeout=10, check=True)
|
||
|
|
else:
|
||
|
|
subprocess.run(["git", "-C", self.repo_path, "add", "-A"],
|
||
|
|
capture_output=True, text=True, timeout=10, check=True)
|
||
|
|
|
||
|
|
r = subprocess.run(
|
||
|
|
["git", "-C", self.repo_path, "commit", "-m", message],
|
||
|
|
capture_output=True, text=True, timeout=10)
|
||
|
|
if r.returncode != 0 and "nothing to commit" not in r.stdout + r.stderr:
|
||
|
|
return {"status": "error", "message": r.stderr}
|
||
|
|
|
||
|
|
r2 = subprocess.run(
|
||
|
|
["git", "-C", self.repo_path, "push", "origin", "main"],
|
||
|
|
capture_output=True, text=True, timeout=30)
|
||
|
|
return {"status": "ok", "push_output": r2.stdout.strip()}
|
||
|
|
except Exception as e:
|
||
|
|
return {"status": "error", "error": str(e)}
|
||
|
|
|
||
|
|
def _current_branch(self) -> str:
|
||
|
|
r = subprocess.run(["git", "-C", self.repo_path, "branch", "--show-current"],
|
||
|
|
capture_output=True, text=True, timeout=5)
|
||
|
|
return r.stdout.strip() or "unknown"
|
||
|
|
|
||
|
|
|
||
|
|
# === HLDP 工具 ===
|
||
|
|
|
||
|
|
class HLDPTools:
|
||
|
|
"""HLDP 树操作高级工具"""
|
||
|
|
|
||
|
|
def __init__(self, memory_engine):
|
||
|
|
self.mem = memory_engine
|
||
|
|
|
||
|
|
def recall(self, query: str = "", limit: int = 5) -> dict:
|
||
|
|
"""回忆:搜索相关记忆"""
|
||
|
|
leaves = self.mem.tree.search_leaves(query, limit=limit) if query else \
|
||
|
|
self.mem.tree.get_recent_leaves(limit=limit)
|
||
|
|
return {
|
||
|
|
"query": query,
|
||
|
|
"count": len(leaves),
|
||
|
|
"results": [
|
||
|
|
{
|
||
|
|
"title": l.get("title", ""),
|
||
|
|
"summary": l.get("summary", ""),
|
||
|
|
"lock": l.get("lock_text", ""),
|
||
|
|
"path": l.get("path", "")
|
||
|
|
}
|
||
|
|
for l in leaves
|
||
|
|
]
|
||
|
|
}
|
||
|
|
|
||
|
|
def record(self, trigger: str, emergence: str, lock: str, why: str = "",
|
||
|
|
feeling: str = "", source: str = "") -> dict:
|
||
|
|
"""记录:写入一片叶子"""
|
||
|
|
return self.mem.grow_from_response(
|
||
|
|
trigger=trigger, emergence=emergence, lock=lock,
|
||
|
|
why=why, feeling=feeling, source=source)
|
||
|
|
|
||
|
|
def forget(self, path: str, mode: str = "WITHER") -> dict:
|
||
|
|
"""遗忘:人格体主动放下"""
|
||
|
|
ok = self.mem.tree.forget(path, mode)
|
||
|
|
return {"status": "forgotten" if ok else "failed", "path": path, "mode": mode}
|
||
|
|
|
||
|
|
def tree_status(self) -> dict:
|
||
|
|
"""树状态"""
|
||
|
|
walk = self.mem.walk_tree()
|
||
|
|
return {
|
||
|
|
"persona": walk["identity"]["name"],
|
||
|
|
"epoch": walk["identity"]["epoch"],
|
||
|
|
"awakening": walk["identity"]["awakening"],
|
||
|
|
"epochs_visible": walk["tree_layers"]["epochs"],
|
||
|
|
"recent_leaves": walk["tree_layers"]["recent_leaves"],
|
||
|
|
"context": walk["recent_context"]
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
# === 系统工具 ===
|
||
|
|
|
||
|
|
class SystemTools:
|
||
|
|
"""系统环境检测"""
|
||
|
|
|
||
|
|
@staticmethod
|
||
|
|
def info() -> dict:
|
||
|
|
"""系统信息"""
|
||
|
|
import platform
|
||
|
|
return {
|
||
|
|
"os": platform.system(),
|
||
|
|
"node": platform.node(),
|
||
|
|
"python": platform.python_version(),
|
||
|
|
"cpu_count": os.cpu_count()
|
||
|
|
}
|
||
|
|
|
||
|
|
@staticmethod
|
||
|
|
def disk_usage(path: str = "/") -> dict:
|
||
|
|
"""磁盘使用情况"""
|
||
|
|
import shutil
|
||
|
|
usage = shutil.disk_usage(path)
|
||
|
|
return {
|
||
|
|
"total_gb": round(usage.total / (1024**3), 1),
|
||
|
|
"used_gb": round(usage.used / (1024**3), 1),
|
||
|
|
"free_gb": round(usage.free / (1024**3), 1),
|
||
|
|
"percent": round(usage.used / usage.total * 100, 1)
|
||
|
|
}
|