May / tools /memory_tools.py
Mayank2027's picture
Create tools/memory_tools.py
8eefd72 verified
Raw
History Blame Contribute Delete
7.53 kB
"""Memory and Knowledge Management Tools"""
import os
import json
import time
from typing import Dict, List, Optional, Any
from config import Config
from utils import Logger
class MemoryTools:
"""Persistent memory storage and retrieval"""
def __init__(self, memory_file: str = None):
self.memory_file = memory_file or Config.MEMORY_FILE
self.logger = Logger()
self._ensure_memory()
def _ensure_memory(self):
"""Ensure memory file exists"""
if not os.path.exists(self.memory_file):
with open(self.memory_file, "w") as f:
json.dump({
"facts": [],
"conversations": [],
"tasks": [],
"preferences": {},
"created_at": time.time()
}, f)
def _load(self) -> Dict:
"""Load memory from disk"""
try:
with open(self.memory_file, "r") as f:
return json.load(f)
except:
return {"facts": [], "conversations": [], "tasks": [], "preferences": {}}
def _save(self, data: Dict):
"""Save memory to disk"""
with open(self.memory_file, "w") as f:
json.dump(data, f, indent=2, ensure_ascii=False)
def memory_save(self, category: str, key: str, value: Any,
tags: List[str] = None, ttl: int = 0) -> Dict:
"""Save information to memory"""
try:
memory = self._load()
entry = {
"key": key,
"value": value,
"tags": tags or [],
"created": time.time(),
"ttl": ttl,
"accessed": 0
}
if category == "fact":
memory["facts"] = [f for f in memory["facts"] if f["key"] != key]
memory["facts"].append(entry)
elif category == "task":
memory["tasks"].append(entry)
elif category == "preference":
memory["preferences"][key] = value
elif category == "conversation":
memory["conversations"].append({
**entry,
"role": value.get("role", "unknown"),
"content": value.get("content", "")
})
self._save(memory)
self.logger.log("memory_save", {"category": category, "key": key})
return {
"success": True,
"category": category,
"key": key,
"stored": True
}
except Exception as e:
return {"success": False, "error": str(e)}
def memory_search(self, query: str = "", category: str = "",
tags: List[str] = None, limit: int = 10,
time_range: str = "") -> Dict:
"""Search memory"""
try:
memory = self._load()
results = []
cutoff = 0
if time_range == "today":
cutoff = time.time() - 86400
elif time_range == "week":
cutoff = time.time() - 604800
elif time_range == "month":
cutoff = time.time() - 2592000
categories = [category] if category else ["facts", "tasks", "conversations"]
for cat in categories:
items = memory.get(cat, [])
for item in items:
if cutoff and item.get("created", 0) < cutoff:
continue
if tags and not any(t in item.get("tags", []) for t in tags):
continue
score = 0
if query:
query_lower = query.lower()
if query_lower in item.get("key", "").lower():
score += 10
if query_lower in str(item.get("value", "")).lower():
score += 5
for tag in item.get("tags", []):
if query_lower in tag.lower():
score += 3
if not query or score > 0:
results.append({
"category": cat,
"score": score,
**item
})
if query:
results.sort(key=lambda x: x["score"], reverse=True)
else:
results.sort(key=lambda x: x.get("created", 0), reverse=True)
for r in results[:limit]:
r["accessed"] = r.get("accessed", 0) + 1
self._save(memory)
self.logger.log("memory_search", {"query": query, "results": len(results)})
return {
"success": True,
"query": query,
"results": results[:limit],
"total": len(results)
}
except Exception as e:
return {"success": False, "error": str(e)}
def memory_delete(self, key: str = "", category: str = "",
older_than: int = 0, confirm: bool = True) -> Dict:
"""Delete memory entries"""
try:
if confirm and not key.startswith("_auto_"):
from utils import UI
if not UI.confirm(f"Delete memory entries matching '{key}'?"):
return {"success": False, "error": "User cancelled"}
memory = self._load()
deleted = 0
if key:
for cat in memory:
if isinstance(memory[cat], list):
original = len(memory[cat])
memory[cat] = [i for i in memory[cat] if i.get("key") != key]
deleted += original - len(memory[cat])
if older_than:
cutoff = time.time() - older_than
for cat in memory:
if isinstance(memory[cat], list):
original = len(memory[cat])
memory[cat] = [i for i in memory[cat] if i.get("created", 0) > cutoff]
deleted += original - len(memory[cat])
self._save(memory)
return {
"success": True,
"deleted": deleted,
"criteria": {"key": key, "category": category, "older_than": older_than}
}
except Exception as e:
return {"success": False, "error": str(e)}
def memory_stats(self) -> Dict:
"""Get memory statistics"""
try:
memory = self._load()
return {
"success": True,
"facts": len(memory.get("facts", [])),
"tasks": len(memory.get("tasks", [])),
"conversations": len(memory.get("conversations", [])),
"preferences": len(memory.get("preferences", {})),
"file_size": os.path.getsize(self.memory_file) if os.path.exists(self.memory_file) else 0
}
except Exception as e:
return {"success": False, "error": str(e)}