Spaces:
Running
Running
Commit
·
3855268
1
Parent(s):
aa9003d
Enhance memo dir and rm duplications
Browse files- memo/REFACTORING_COMPLETE.md +0 -0
- memo/context.py +10 -11
- memo/core.py +26 -7
- memo/history.py +35 -33
- memo/nvidia.py +1 -0
memo/REFACTORING_COMPLETE.md
DELETED
|
File without changes
|
memo/context.py
CHANGED
|
@@ -44,6 +44,7 @@ async def get_conversation_context(user_id: str, question: str, memory_system,
|
|
| 44 |
embedder: EmbeddingClient, topk_sem: int = 3) -> Tuple[str, str]:
|
| 45 |
"""
|
| 46 |
Get both recent and semantic context for conversation continuity.
|
|
|
|
| 47 |
"""
|
| 48 |
try:
|
| 49 |
if memory_system and memory_system.is_enhanced_available():
|
|
@@ -53,7 +54,7 @@ async def get_conversation_context(user_id: str, question: str, memory_system,
|
|
| 53 |
)
|
| 54 |
return recent_context, semantic_context
|
| 55 |
else:
|
| 56 |
-
# Fallback to legacy context
|
| 57 |
return await get_legacy_context(user_id, question, memory_system, embedder, topk_sem)
|
| 58 |
except Exception as e:
|
| 59 |
logger.error(f"[CONTEXT_MANAGER] Context retrieval failed: {e}")
|
|
@@ -61,26 +62,24 @@ async def get_conversation_context(user_id: str, question: str, memory_system,
|
|
| 61 |
|
| 62 |
async def get_legacy_context(user_id: str, question: str, memory_system,
|
| 63 |
embedder: EmbeddingClient, topk_sem: int) -> Tuple[str, str]:
|
| 64 |
-
"""Get context using legacy method"""
|
| 65 |
if not memory_system:
|
| 66 |
return "", ""
|
| 67 |
|
| 68 |
recent3 = memory_system.recent(user_id, 3)
|
| 69 |
rest17 = memory_system.rest(user_id, 3)
|
| 70 |
|
|
|
|
| 71 |
recent_text = ""
|
| 72 |
if recent3:
|
| 73 |
-
|
| 74 |
-
|
|
|
|
|
|
|
| 75 |
|
|
|
|
| 76 |
sem_text = ""
|
| 77 |
if rest17:
|
| 78 |
-
|
| 79 |
-
mats = embedder.embed([s.strip() for s in rest17])
|
| 80 |
-
sims = [(cosine_similarity(qv, np.array(v, dtype="float32")), s) for v, s in zip(mats, rest17)]
|
| 81 |
-
sims.sort(key=lambda x: x[0], reverse=True)
|
| 82 |
-
top = [s for (sc, s) in sims[:topk_sem] if sc > 0.15]
|
| 83 |
-
if top:
|
| 84 |
-
sem_text = "\n\n".join(top)
|
| 85 |
|
| 86 |
return recent_text, sem_text
|
|
|
|
| 44 |
embedder: EmbeddingClient, topk_sem: int = 3) -> Tuple[str, str]:
|
| 45 |
"""
|
| 46 |
Get both recent and semantic context for conversation continuity.
|
| 47 |
+
Enhanced version that uses semantic similarity for better context selection.
|
| 48 |
"""
|
| 49 |
try:
|
| 50 |
if memory_system and memory_system.is_enhanced_available():
|
|
|
|
| 54 |
)
|
| 55 |
return recent_context, semantic_context
|
| 56 |
else:
|
| 57 |
+
# Fallback to legacy context with enhanced semantic selection
|
| 58 |
return await get_legacy_context(user_id, question, memory_system, embedder, topk_sem)
|
| 59 |
except Exception as e:
|
| 60 |
logger.error(f"[CONTEXT_MANAGER] Context retrieval failed: {e}")
|
|
|
|
| 62 |
|
| 63 |
async def get_legacy_context(user_id: str, question: str, memory_system,
|
| 64 |
embedder: EmbeddingClient, topk_sem: int) -> Tuple[str, str]:
|
| 65 |
+
"""Get context using legacy method with enhanced semantic selection"""
|
| 66 |
if not memory_system:
|
| 67 |
return "", ""
|
| 68 |
|
| 69 |
recent3 = memory_system.recent(user_id, 3)
|
| 70 |
rest17 = memory_system.rest(user_id, 3)
|
| 71 |
|
| 72 |
+
# Use semantic similarity to select most relevant recent memories
|
| 73 |
recent_text = ""
|
| 74 |
if recent3:
|
| 75 |
+
try:
|
| 76 |
+
recent_text = await semantic_context(question, recent3, embedder, 2)
|
| 77 |
+
except Exception as e:
|
| 78 |
+
logger.warning(f"[CONTEXT_MANAGER] Recent context selection failed: {e}")
|
| 79 |
|
| 80 |
+
# Get semantic context from remaining memories
|
| 81 |
sem_text = ""
|
| 82 |
if rest17:
|
| 83 |
+
sem_text = await semantic_context(question, rest17, embedder, topk_sem)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
|
| 85 |
return recent_text, sem_text
|
memo/core.py
CHANGED
|
@@ -189,7 +189,7 @@ class MemorySystem:
|
|
| 189 |
logger.warning(f"[CORE_MEMORY] Failed to add enhanced memory: {e}")
|
| 190 |
|
| 191 |
async def _get_enhanced_context(self, user_id: str, question: str) -> Tuple[str, str]:
|
| 192 |
-
"""Get context from enhanced memory system"""
|
| 193 |
try:
|
| 194 |
# Get recent conversation memories
|
| 195 |
recent_memories = self.enhanced_memory.get_memories(
|
|
@@ -199,9 +199,17 @@ class MemorySystem:
|
|
| 199 |
)
|
| 200 |
|
| 201 |
recent_context = ""
|
| 202 |
-
if recent_memories:
|
| 203 |
-
|
| 204 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 205 |
|
| 206 |
# Get semantic context from other memory types
|
| 207 |
semantic_memories = self.enhanced_memory.get_memories(
|
|
@@ -210,11 +218,22 @@ class MemorySystem:
|
|
| 210 |
)
|
| 211 |
|
| 212 |
semantic_context = ""
|
| 213 |
-
if semantic_memories:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 214 |
other_memories = [m for m in semantic_memories if m.get("memory_type") != "conversation"]
|
| 215 |
if other_memories:
|
| 216 |
-
|
| 217 |
-
semantic_context = "\n\n".join(semantic_summaries)
|
| 218 |
|
| 219 |
return recent_context, semantic_context
|
| 220 |
|
|
|
|
| 189 |
logger.warning(f"[CORE_MEMORY] Failed to add enhanced memory: {e}")
|
| 190 |
|
| 191 |
async def _get_enhanced_context(self, user_id: str, question: str) -> Tuple[str, str]:
|
| 192 |
+
"""Get context from enhanced memory system with semantic selection"""
|
| 193 |
try:
|
| 194 |
# Get recent conversation memories
|
| 195 |
recent_memories = self.enhanced_memory.get_memories(
|
|
|
|
| 199 |
)
|
| 200 |
|
| 201 |
recent_context = ""
|
| 202 |
+
if recent_memories and self.embedder:
|
| 203 |
+
# Use semantic similarity to select most relevant recent memories
|
| 204 |
+
try:
|
| 205 |
+
from memo.context import semantic_context
|
| 206 |
+
recent_summaries = [m["summary"] for m in recent_memories]
|
| 207 |
+
recent_context = await semantic_context(question, recent_summaries, self.embedder, 3)
|
| 208 |
+
except Exception as e:
|
| 209 |
+
logger.warning(f"[CORE_MEMORY] Semantic recent context failed, using all: {e}")
|
| 210 |
+
recent_context = "\n\n".join([m["summary"] for m in recent_memories])
|
| 211 |
+
elif recent_memories:
|
| 212 |
+
recent_context = "\n\n".join([m["summary"] for m in recent_memories])
|
| 213 |
|
| 214 |
# Get semantic context from other memory types
|
| 215 |
semantic_memories = self.enhanced_memory.get_memories(
|
|
|
|
| 218 |
)
|
| 219 |
|
| 220 |
semantic_context = ""
|
| 221 |
+
if semantic_memories and self.embedder:
|
| 222 |
+
try:
|
| 223 |
+
from memo.context import semantic_context
|
| 224 |
+
other_memories = [m for m in semantic_memories if m.get("memory_type") != "conversation"]
|
| 225 |
+
if other_memories:
|
| 226 |
+
other_summaries = [m["summary"] for m in other_memories]
|
| 227 |
+
semantic_context = await semantic_context(question, other_summaries, self.embedder, 5)
|
| 228 |
+
except Exception as e:
|
| 229 |
+
logger.warning(f"[CORE_MEMORY] Semantic context failed, using all: {e}")
|
| 230 |
+
other_memories = [m for m in semantic_memories if m.get("memory_type") != "conversation"]
|
| 231 |
+
if other_memories:
|
| 232 |
+
semantic_context = "\n\n".join([m["summary"] for m in other_memories])
|
| 233 |
+
elif semantic_memories:
|
| 234 |
other_memories = [m for m in semantic_memories if m.get("memory_type") != "conversation"]
|
| 235 |
if other_memories:
|
| 236 |
+
semantic_context = "\n\n".join([m["summary"] for m in other_memories])
|
|
|
|
| 237 |
|
| 238 |
return recent_context, semantic_context
|
| 239 |
|
memo/history.py
CHANGED
|
@@ -9,7 +9,7 @@ from typing import List, Dict, Any, Tuple, Optional
|
|
| 9 |
|
| 10 |
from utils.logger import get_logger
|
| 11 |
from memo.nvidia import summarize_qa, files_relevance, related_recent_context
|
| 12 |
-
from memo.context import
|
| 13 |
from utils.embeddings import EmbeddingClient
|
| 14 |
|
| 15 |
logger = get_logger("HISTORY_MANAGER", __name__)
|
|
@@ -48,48 +48,50 @@ class HistoryManager:
|
|
| 48 |
except Exception as e:
|
| 49 |
logger.error(f"[HISTORY_MANAGER] Context retrieval failed: {e}")
|
| 50 |
return "", ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
|
| 52 |
# ────────────────────────────── Legacy Functions (Backward Compatibility) ──────────────────────────────
|
| 53 |
|
| 54 |
async def summarize_qa_with_nvidia(question: str, answer: str, rotator) -> str:
|
| 55 |
-
"""
|
| 56 |
-
Returns a single line block:
|
| 57 |
-
q: <concise>\na: <concise>
|
| 58 |
-
No extra commentary.
|
| 59 |
-
"""
|
| 60 |
return await summarize_qa(question, answer, rotator)
|
| 61 |
|
| 62 |
async def files_relevance(question: str, file_summaries: List[Dict[str, str]], rotator) -> Dict[str, bool]:
|
| 63 |
-
"""
|
| 64 |
-
Ask NVIDIA model to mark each file as relevant (true) or not (false) for the question.
|
| 65 |
-
Returns {filename: bool}
|
| 66 |
-
"""
|
| 67 |
return await files_relevance(question, file_summaries, rotator)
|
| 68 |
|
| 69 |
async def related_recent_and_semantic_context(user_id: str, question: str, memory, embedder: EmbeddingClient, topk_sem: int = 3) -> Tuple[str, str]:
|
| 70 |
-
"""
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
This function is maintained for backward compatibility.
|
| 76 |
-
For enhanced features, use the integrated memory system.
|
| 77 |
-
"""
|
| 78 |
-
recent3 = memory.recent(user_id, 3)
|
| 79 |
-
rest17 = memory.rest(user_id, 3)
|
| 80 |
-
|
| 81 |
-
recent_text = ""
|
| 82 |
-
if recent3:
|
| 83 |
-
# This would need NVIDIA processing in the calling code
|
| 84 |
-
pass
|
| 85 |
-
|
| 86 |
-
# Semantic over rest17
|
| 87 |
-
sem_text = ""
|
| 88 |
-
if rest17:
|
| 89 |
-
sem_text = await semantic_context(question, rest17, embedder, topk_sem)
|
| 90 |
-
|
| 91 |
-
# Return recent empty (to be filled by caller using NVIDIA), and semantic text
|
| 92 |
-
return ("", sem_text)
|
| 93 |
|
| 94 |
# ────────────────────────────── Global Instance ──────────────────────────────
|
| 95 |
|
|
|
|
| 9 |
|
| 10 |
from utils.logger import get_logger
|
| 11 |
from memo.nvidia import summarize_qa, files_relevance, related_recent_context
|
| 12 |
+
from memo.context import semantic_context
|
| 13 |
from utils.embeddings import EmbeddingClient
|
| 14 |
|
| 15 |
logger = get_logger("HISTORY_MANAGER", __name__)
|
|
|
|
| 48 |
except Exception as e:
|
| 49 |
logger.error(f"[HISTORY_MANAGER] Context retrieval failed: {e}")
|
| 50 |
return "", ""
|
| 51 |
+
|
| 52 |
+
async def _get_legacy_context(self, user_id: str, question: str, memory_system,
|
| 53 |
+
embedder: EmbeddingClient, topk_sem: int) -> Tuple[str, str]:
|
| 54 |
+
"""Get context using legacy method with enhanced semantic selection"""
|
| 55 |
+
if not memory_system:
|
| 56 |
+
return "", ""
|
| 57 |
+
|
| 58 |
+
recent3 = memory_system.recent(user_id, 3)
|
| 59 |
+
rest17 = memory_system.rest(user_id, 3)
|
| 60 |
+
|
| 61 |
+
recent_text = ""
|
| 62 |
+
if recent3:
|
| 63 |
+
# Use NVIDIA to select most relevant recent memories (enhanced)
|
| 64 |
+
try:
|
| 65 |
+
recent_text = await related_recent_context(question, recent3, None) # rotator will be passed by caller
|
| 66 |
+
except Exception as e:
|
| 67 |
+
logger.warning(f"[HISTORY_MANAGER] Recent context selection failed: {e}")
|
| 68 |
+
# Fallback to semantic similarity
|
| 69 |
+
try:
|
| 70 |
+
recent_text = await semantic_context(question, recent3, embedder, 2)
|
| 71 |
+
except Exception as e2:
|
| 72 |
+
logger.warning(f"[HISTORY_MANAGER] Semantic fallback failed: {e2}")
|
| 73 |
+
|
| 74 |
+
sem_text = ""
|
| 75 |
+
if rest17:
|
| 76 |
+
sem_text = await semantic_context(question, rest17, embedder, topk_sem)
|
| 77 |
+
|
| 78 |
+
return recent_text, sem_text
|
| 79 |
|
| 80 |
# ────────────────────────────── Legacy Functions (Backward Compatibility) ──────────────────────────────
|
| 81 |
|
| 82 |
async def summarize_qa_with_nvidia(question: str, answer: str, rotator) -> str:
|
| 83 |
+
"""Legacy function - use HistoryManager.summarize_qa_with_nvidia() instead"""
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
return await summarize_qa(question, answer, rotator)
|
| 85 |
|
| 86 |
async def files_relevance(question: str, file_summaries: List[Dict[str, str]], rotator) -> Dict[str, bool]:
|
| 87 |
+
"""Legacy function - use HistoryManager.files_relevance() instead"""
|
|
|
|
|
|
|
|
|
|
| 88 |
return await files_relevance(question, file_summaries, rotator)
|
| 89 |
|
| 90 |
async def related_recent_and_semantic_context(user_id: str, question: str, memory, embedder: EmbeddingClient, topk_sem: int = 3) -> Tuple[str, str]:
|
| 91 |
+
"""Legacy function - use HistoryManager.related_recent_and_semantic_context() instead"""
|
| 92 |
+
# Create a temporary history manager for legacy compatibility
|
| 93 |
+
history_manager = HistoryManager(memory)
|
| 94 |
+
return await history_manager.related_recent_and_semantic_context(user_id, question, embedder, topk_sem)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
|
| 96 |
# ────────────────────────────── Global Instance ──────────────────────────────
|
| 97 |
|
memo/nvidia.py
CHANGED
|
@@ -104,6 +104,7 @@ async def files_relevance(question: str, file_summaries: List[Dict[str, str]], r
|
|
| 104 |
async def related_recent_context(question: str, recent_memories: List[str], rotator) -> str:
|
| 105 |
"""
|
| 106 |
Use NVIDIA to select related items from recent memories.
|
|
|
|
| 107 |
"""
|
| 108 |
if not recent_memories:
|
| 109 |
return ""
|
|
|
|
| 104 |
async def related_recent_context(question: str, recent_memories: List[str], rotator) -> str:
|
| 105 |
"""
|
| 106 |
Use NVIDIA to select related items from recent memories.
|
| 107 |
+
Enhanced function for better context memory ability.
|
| 108 |
"""
|
| 109 |
if not recent_memories:
|
| 110 |
return ""
|