fix: opencode code review 修复
- cbm-to-zhiyi.py: 防止 KeyError(.get 防御) - cbm-query-wrapper.py: 异常细化 + 环境变量读取 API key + nodes/edges 类型安全 - update_profile.py: 变更检测避免冗余写入 + agent_id 统一为 a06
This commit is contained in:
parent
a4f3327e4e
commit
a030cc0a0e
|
|
@ -6,11 +6,11 @@ cbm-query-wrapper.py — P3: CBM 查询钩子
|
|||
python3 cbm-query-wrapper.py search_graph --project X --name-pattern Y
|
||||
python3 cbm-query-wrapper.py get_architecture --project X
|
||||
"""
|
||||
import json, os, subprocess, sys, urllib.request
|
||||
import json, os, subprocess, sys, urllib.request, urllib.error
|
||||
|
||||
CBM = os.path.expanduser("~/.local/bin/codebase-memory-mcp")
|
||||
ZHIYI_URL = "http://localhost:7821/api/v1/commit"
|
||||
ZHIYI_KEY = "zhiyi-dev-key-2026"
|
||||
ZHIYI_KEY = os.environ.get("ZHIYI_API_KEY", "zhiyi-dev-key-2026")
|
||||
|
||||
def zhiyi_write(content, category="distilled"):
|
||||
"""写入织忆"""
|
||||
|
|
@ -23,14 +23,23 @@ def zhiyi_write(content, category="distilled"):
|
|||
headers={"X-API-Key": ZHIYI_KEY, "Content-Type": "application/json"})
|
||||
try:
|
||||
urllib.request.urlopen(req, timeout=5)
|
||||
except Exception:
|
||||
pass # 写入失败不影响主查询
|
||||
return True
|
||||
except urllib.error.URLError as e:
|
||||
print(f"[cbm-wrapper] ⚠ 织忆写入失败: {e}", file=sys.stderr)
|
||||
return False
|
||||
|
||||
def run_cbm(args):
|
||||
"""执行 CBM CLI 并返回 JSON 结果"""
|
||||
cmd = [CBM, "cli"] + args
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
|
||||
return result.stdout, result.returncode
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
|
||||
return result.stdout, result.returncode
|
||||
except FileNotFoundError:
|
||||
print(f"[cbm-wrapper] ❌ CBM binary not found: {CBM}", file=sys.stderr)
|
||||
return "", 1
|
||||
except subprocess.TimeoutExpired:
|
||||
print(f"[cbm-wrapper] ⚠ CBM timed out (60s)", file=sys.stderr)
|
||||
return "", 1
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
|
|
@ -51,23 +60,22 @@ def main():
|
|||
try:
|
||||
data = json.loads(stdout)
|
||||
project = data.get("project", data.get("name", "unknown"))
|
||||
nodes = data.get("nodes", data.get("total_nodes", 0))
|
||||
edges = data.get("edges", data.get("total_edges", 0))
|
||||
nodes = data.get("nodes") or data.get("total_nodes") or 0
|
||||
edges = data.get("edges") or data.get("total_edges") or 0
|
||||
|
||||
if tool in ("index_repository",) and nodes:
|
||||
if tool in ("index_repository",) and int(nodes) > 0:
|
||||
content = f"CBM索引完成: {project} ({nodes}节点/{edges}边)"
|
||||
zhiyi_write(content)
|
||||
elif tool in ("get_architecture", "list_projects"):
|
||||
# 只保存摘要
|
||||
content = f"CBM架构查询: {project}"
|
||||
zhiyi_write(content)
|
||||
elif tool in ("search_graph", "trace_path"):
|
||||
results = data.get("results", data.get("nodes", []))
|
||||
results = data.get("results") or data.get("nodes") or []
|
||||
if results:
|
||||
names = [r.get("name","?") for r in results[:5]]
|
||||
content = f"CBM查询 '{' '.join(sys.argv)}': 找到 {len(results)} 个结果 ({', '.join(names)})"
|
||||
content = f"CBM查询 '{tool}': 找到 {len(results)} 个结果 ({', '.join(names)})"
|
||||
zhiyi_write(content)
|
||||
except (json.JSONDecodeError, KeyError):
|
||||
except (json.JSONDecodeError, KeyError, TypeError, ValueError):
|
||||
pass # 非 JSON 输出或不匹配模式就不写入
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
|
|
@ -29,7 +29,10 @@ def main():
|
|||
|
||||
lines = ["CBM代码图谱状态:"]
|
||||
for p in projects:
|
||||
lines.append(f" • {p['name']}: {p['nodes']}节点/{p['edges']}边")
|
||||
name = p.get('name', '?')
|
||||
nodes = p.get('nodes', 0)
|
||||
edges = p.get('edges', 0)
|
||||
lines.append(f" • {name}: {nodes}节点/{edges}边")
|
||||
content = "\n".join(lines)
|
||||
|
||||
# 写入织忆
|
||||
|
|
|
|||
|
|
@ -312,15 +312,29 @@ def main():
|
|||
|
||||
# ── P1: Soulful → 织忆 ──────────────────────────────────
|
||||
profile = up.get()
|
||||
style = profile.get("communication_style", "unknown")
|
||||
goals = profile.get("current_goals", [])
|
||||
emotion = profile.get("emotional_state", {}).get("current", "unknown")
|
||||
content = f"用户画像更新: 风格={style} 情绪={emotion} 目标={', '.join(goals[:3])}"
|
||||
try:
|
||||
zhiyi_write(content, "distilled")
|
||||
print(f" ✓ 画像 → 织忆")
|
||||
except Exception as e:
|
||||
print(f" ⚠ 织忆写入失败: {e}")
|
||||
style = profile.get("communication_style", style) # 用 fresh 检测值优先
|
||||
goals = profile.get("current_goals", goals)
|
||||
emotion = profile.get("emotional_state", {}).get("current", emotion)
|
||||
|
||||
# 变更检测:只有画像发生变化才写入织忆
|
||||
last_hash_file = os.path.join(HERMES, "soulful", ".last_zhiyi_hash")
|
||||
current_hash = f"{style}|{emotion}|{','.join(goals[:3])}"
|
||||
last_hash = ""
|
||||
if os.path.exists(last_hash_file):
|
||||
with open(last_hash_file) as f:
|
||||
last_hash = f.read().strip()
|
||||
|
||||
if current_hash != last_hash:
|
||||
content = f"用户画像更新: 风格={style} 情绪={emotion} 目标={', '.join(goals[:3])}"
|
||||
try:
|
||||
zhiyi_write(content, "distilled")
|
||||
with open(last_hash_file, 'w') as f:
|
||||
f.write(current_hash)
|
||||
print(f" ✓ 画像 → 织忆")
|
||||
except Exception as e:
|
||||
print(f" ⚠ 织忆写入失败: {e}")
|
||||
else:
|
||||
print(f" - 画像无变化,跳过织忆写入")
|
||||
# ── P1 End ──────────────────────────────────────────────
|
||||
|
||||
|
||||
|
|
@ -330,7 +344,7 @@ def zhiyi_write(content: str, category: str = "distilled"):
|
|||
payload = json.dumps({
|
||||
"content": content,
|
||||
"category": category,
|
||||
"agent_id": "hermes-a06"
|
||||
"agent_id": "a06"
|
||||
}).encode()
|
||||
req = urllib.request.Request(
|
||||
"http://localhost:7821/api/v1/commit",
|
||||
|
|
|
|||
Loading…
Reference in New Issue