qwen-hackthon / tools /memory_tool.py
Yousef
Add all project files
f97e4ec
Raw
History Blame Contribute Delete
3.35 kB
from tools.definitions import tool
from config import client
import sqlite3
import json
import time
import os
MEMORY_DB = os.path.join(os.path.dirname(__file__), "..", "memory.db")
def get_embedding(text: str):
resp = client.embeddings.create(
model="text-embedding-v4",
input=text
)
return resp.data[0].embedding
@tool(
name="store_memory",
description="Store a fact or memory that should be remembered across conversations.",
parameters={
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "A unique identifier or topic for this memory"
},
"content": {
"type": "string",
"description": "The fact or information to remember"
},
"category": {
"type": "string",
"description": "Category like user_preference, fact, instruction, summary",
"default": "fact"
}
},
"required": ["key", "content"]
}
)
def store_memory(key: str, content: str, category: str = "fact"):
conn = sqlite3.connect(MEMORY_DB)
conn.execute("""
CREATE TABLE IF NOT EXISTS vector_memory (
id INTEGER PRIMARY KEY AUTOINCREMENT,
key TEXT UNIQUE,
content TEXT,
category TEXT,
embedding BLOB,
created_at REAL
)
""")
emb = get_embedding(key + ": " + content)
emb_blob = json.dumps(emb)
conn.execute(
"INSERT OR REPLACE INTO vector_memory (key, content, category, embedding, created_at) VALUES (?, ?, ?, ?, ?)",
(key, content, category, emb_blob, time.time())
)
conn.commit()
conn.close()
return {"status": "stored", "key": key}
@tool(
name="recall_memories",
description="Search for relevant memories based on a query. Returns the most relevant stored facts.",
parameters={
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "What to search for in memory"
},
"n": {
"type": "integer",
"description": "Number of results to return (max 10)",
"default": 5
}
},
"required": ["query"]
}
)
def recall_memories(query: str, n: int = 5):
conn = sqlite3.connect(MEMORY_DB)
try:
rows = conn.execute("SELECT key, content, category, embedding FROM vector_memory").fetchall()
except:
conn.close()
return {"results": [], "note": "No memories stored yet"}
query_emb = get_embedding(query)
scored = []
for key, content, category, emb_blob in rows:
stored_emb = json.loads(emb_blob)
score = cosine_similarity(query_emb, stored_emb)
scored.append((score, key, content, category))
scored.sort(reverse=True)
conn.close()
return {
"results": [
{"key": k, "content": c, "category": cat, "relevance": round(s, 3)}
for s, k, c, cat in scored[:n]
]
}
def cosine_similarity(a, b):
dot = sum(x * y for x, y in zip(a, b))
na = sum(x * x for x in a) ** 0.5
nb = sum(x * x for x in b) ** 0.5
return dot / (na * nb) if na and nb else 0