149 lines
4.2 KiB
Python
149 lines
4.2 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
OpenClaw 向量记忆系统 Skill
|
||
用于 OpenClaw 主系统调用
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
import json
|
||
|
||
# 添加项目路径
|
||
VECTOR_DIR = os.path.expanduser("~/openclaw-memory-vector")
|
||
sys.path.insert(0, VECTOR_DIR)
|
||
|
||
from vector_memory import VectorMemorySystem
|
||
from memory_backup import MemoryBackup
|
||
|
||
|
||
class MemoryVectorSkill:
|
||
"""向量记忆 skill"""
|
||
|
||
def __init__(self):
|
||
self.api_key = os.getenv("SILICONFLOW_API_KEY", "sk-fpjdtxbxrhtekshircjhegstloxaodriekotjdyzzktyegcl")
|
||
self.vm = None
|
||
|
||
def _get_vm(self):
|
||
"""获取向量记忆系统实例"""
|
||
if not self.vm:
|
||
self.vm = VectorMemorySystem(
|
||
api_key=self.api_key,
|
||
persist_dir=os.path.join(VECTOR_DIR, "data/memory")
|
||
)
|
||
return self.vm
|
||
|
||
def search(self, query: str) -> str:
|
||
"""搜索记忆"""
|
||
vm = self._get_vm()
|
||
results = vm.search(query, top_k=5)
|
||
|
||
if not results:
|
||
return f"没有找到与「{query}」相关的记忆"
|
||
|
||
lines = [f"🔍 搜索「{query}」找到 {len(results)} 条相关记忆:\n"]
|
||
|
||
for i, r in enumerate(results, 1):
|
||
similarity = r['similarity'] * 100
|
||
lines.append(f"{i}. {r['content'][:60]}...")
|
||
lines.append(f" 相似度: {similarity:.1f}%")
|
||
lines.append("")
|
||
|
||
return "\n".join(lines)
|
||
|
||
def add(self, content: str, importance: int = 3, tags: list = None) -> str:
|
||
"""添加记忆"""
|
||
vm = self._get_vm()
|
||
metadata = {"tags": tags or []} if tags else {}
|
||
|
||
vm.add_memory(content, metadata, importance)
|
||
|
||
stars = "⭐" * importance
|
||
return f"✅ 已添加记忆 [{stars}]:{content[:40]}..."
|
||
|
||
def recent(self, limit: int = 10) -> str:
|
||
"""查看最近记忆"""
|
||
vm = self._get_vm()
|
||
results = vm.get_recent(limit)
|
||
|
||
if not results:
|
||
return "还没有任何记忆"
|
||
|
||
lines = [f"📅 最近 {len(results)} 条记忆:\n"]
|
||
|
||
for i, r in enumerate(results, 1):
|
||
stars = "⭐" * r['importance']
|
||
lines.append(f"{i}. [{stars}] {r['content'][:50]}...")
|
||
lines.append(f" 时间: {r['created_at']}")
|
||
lines.append("")
|
||
|
||
return "\n".join(lines)
|
||
|
||
def count(self) -> str:
|
||
"""记忆统计"""
|
||
vm = self._get_vm()
|
||
total = vm.count()
|
||
return f"📊 当前记忆总数: **{total}** 条"
|
||
|
||
def backup(self) -> str:
|
||
"""手动备份"""
|
||
backup = MemoryBackup()
|
||
vm = self._get_vm()
|
||
result = backup.backup_all(vm)
|
||
|
||
return f"""✅ 备份完成!
|
||
- JSON: {result['json']}
|
||
- Markdown: {result['markdown']}
|
||
- 向量库: {result['vector']}"""
|
||
|
||
|
||
def main():
|
||
"""CLI 入口"""
|
||
if len(sys.argv) < 2:
|
||
print("用法: python3 skill.py <command> [args...]")
|
||
print("命令: search <query>")
|
||
print(" add <content> [--importance N] [--tags tag1,tag2]")
|
||
print(" recent [N]")
|
||
print(" count")
|
||
print(" backup")
|
||
sys.exit(1)
|
||
|
||
skill = MemoryVectorSkill()
|
||
command = sys.argv[1]
|
||
|
||
if command == "search":
|
||
query = " ".join(sys.argv[2:])
|
||
print(skill.search(query))
|
||
|
||
elif command == "add":
|
||
content = sys.argv[2]
|
||
importance = 3
|
||
tags = []
|
||
|
||
# 解析参数
|
||
for i, arg in enumerate(sys.argv[3:]):
|
||
if arg == "--importance" and i+3 < len(sys.argv):
|
||
importance = int(sys.argv[i+4])
|
||
elif arg == "--tags" and i+3 < len(sys.argv):
|
||
tags = sys.argv[i+4].split(",")
|
||
|
||
print(skill.add(content, importance, tags))
|
||
|
||
elif command == "recent":
|
||
limit = int(sys.argv[2]) if len(sys.argv) > 2 else 10
|
||
print(skill.recent(limit))
|
||
|
||
elif command == "count":
|
||
print(skill.count())
|
||
|
||
elif command == "backup":
|
||
print(skill.backup())
|
||
|
||
else:
|
||
print(f"未知命令: {command}")
|
||
sys.exit(1)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|