feat(memory_system): introduce "Intermediate" status level for more granular status emission control

Adds an "Intermediate" status level between "Basic" and "Detailed" to provide
summaries and key details, updates all relevant mappings and usages to support
this new level, and adjusts default verbosity for status messages to improve
clarity and reduce noise for users who do not require full diagnostics.
This commit is contained in:
mtayfur
2025-11-15 21:51:22 +03:00
parent 6ae99d4778
commit 960f8ce4a9

View File

@@ -66,12 +66,14 @@ class Constants:
# Status Emit Levels # Status Emit Levels
STATUS_LEVEL_BASIC = 0 # Maps to "Basic" - Show only summary counts STATUS_LEVEL_BASIC = 0 # Maps to "Basic" - Show only summary counts
STATUS_LEVEL_DETAILED = 1 # Maps to "Detailed" - Show everything including full diagnostics STATUS_LEVEL_INTERMEDIATE = 1 # Maps to "Intermediate" - Show summaries and key details
STATUS_LEVEL_DETAILED = 2 # Maps to "Detailed" - Show everything including full diagnostics
# Mapping from enum string values to numeric levels for comparison # Mapping from enum string values to numeric levels for comparison
STATUS_LEVEL_MAP = { STATUS_LEVEL_MAP = {
"Basic": 0, "Basic": 0,
"Detailed": 1, "Intermediate": 1,
"Detailed": 2,
} }
@@ -205,6 +207,7 @@ class Models:
"""Verbosity levels for status message emission - selectable as dropdown with title case strings.""" """Verbosity levels for status message emission - selectable as dropdown with title case strings."""
BASIC = "Basic" BASIC = "Basic"
INTERMEDIATE = "Intermediate"
DETAILED = "Detailed" DETAILED = "Detailed"
class MemoryOperationType(Enum): class MemoryOperationType(Enum):
@@ -740,7 +743,7 @@ CANDIDATE MEMORIES:
emitter, emitter,
f"🤖 LLM Analyzing {len(llm_candidates)} Memories for Relevance", f"🤖 LLM Analyzing {len(llm_candidates)} Memories for Relevance",
done=False, done=False,
level=Constants.STATUS_LEVEL_DETAILED, level=Constants.STATUS_LEVEL_INTERMEDIATE,
) )
logger.info(f"Using LLM reranking: {decision_reason}") logger.info(f"Using LLM reranking: {decision_reason}")
@@ -748,7 +751,9 @@ CANDIDATE MEMORIES:
if not selected_memories: if not selected_memories:
logger.info("📭 No relevant memories after LLM analysis") logger.info("📭 No relevant memories after LLM analysis")
await self.memory_system._emit_status(emitter, f"📭 No Relevant Memories After LLM Analysis", done=True, level=Constants.STATUS_LEVEL_BASIC) await self.memory_system._emit_status(
emitter, f"📭 No Relevant Memories After LLM Analysis", done=True, level=Constants.STATUS_LEVEL_INTERMEDIATE
)
return selected_memories, analysis_info return selected_memories, analysis_info
else: else:
logger.info(f"Skipping LLM reranking: {decision_reason}") logger.info(f"Skipping LLM reranking: {decision_reason}")
@@ -1033,27 +1038,27 @@ class LLMConsolidationService:
if isinstance(result, Exception): if isinstance(result, Exception):
failed_count += 1 failed_count += 1
await self.memory_system._emit_status(emitter, f"❌ Failed {operation_type}", done=False, level=Constants.STATUS_LEVEL_BASIC) await self.memory_system._emit_status(emitter, f"❌ Failed {operation_type}", done=False, level=Constants.STATUS_LEVEL_INTERMEDIATE)
elif result == Models.MemoryOperationType.CREATE.value: elif result == Models.MemoryOperationType.CREATE.value:
created_count += 1 created_count += 1
content_preview = self.memory_system._truncate_content(operation.content) content_preview = self.memory_system._truncate_content(operation.content)
await self.memory_system._emit_status(emitter, f"📝 Created: {content_preview}", done=False, level=Constants.STATUS_LEVEL_DETAILED) await self.memory_system._emit_status(emitter, f"📝 Created: {content_preview}", done=False, level=Constants.STATUS_LEVEL_INTERMEDIATE)
elif result == Models.MemoryOperationType.UPDATE.value: elif result == Models.MemoryOperationType.UPDATE.value:
updated_count += 1 updated_count += 1
content_preview = self.memory_system._truncate_content(operation.content) content_preview = self.memory_system._truncate_content(operation.content)
await self.memory_system._emit_status(emitter, f"✏️ Updated: {content_preview}", done=False, level=Constants.STATUS_LEVEL_DETAILED) await self.memory_system._emit_status(emitter, f"✏️ Updated: {content_preview}", done=False, level=Constants.STATUS_LEVEL_INTERMEDIATE)
elif result == Models.MemoryOperationType.DELETE.value: elif result == Models.MemoryOperationType.DELETE.value:
deleted_count += 1 deleted_count += 1
content_preview = memory_contents_for_deletion.get(operation.id, operation.id) content_preview = memory_contents_for_deletion.get(operation.id, operation.id)
if content_preview and content_preview != operation.id: if content_preview and content_preview != operation.id:
content_preview = self.memory_system._truncate_content(content_preview) content_preview = self.memory_system._truncate_content(content_preview)
await self.memory_system._emit_status(emitter, f"🗑️ Deleted: {content_preview}", done=False, level=Constants.STATUS_LEVEL_DETAILED) await self.memory_system._emit_status(emitter, f"🗑️ Deleted: {content_preview}", done=False, level=Constants.STATUS_LEVEL_INTERMEDIATE)
elif result in [ elif result in [
Models.OperationResult.FAILED.value, Models.OperationResult.FAILED.value,
Models.OperationResult.UNSUPPORTED.value, Models.OperationResult.UNSUPPORTED.value,
]: ]:
failed_count += 1 failed_count += 1
await self.memory_system._emit_status(emitter, f"❌ Failed {operation_type}", done=False, level=Constants.STATUS_LEVEL_BASIC) await self.memory_system._emit_status(emitter, f"❌ Failed {operation_type}", done=False, level=Constants.STATUS_LEVEL_INTERMEDIATE)
total_executed = created_count + updated_count + deleted_count total_executed = created_count + updated_count + deleted_count
logger.info( logger.info(
@@ -1156,9 +1161,9 @@ class Filter:
default=Constants.SKIP_CATEGORY_MARGIN, default=Constants.SKIP_CATEGORY_MARGIN,
description="Margin above personal similarity for skip category classification (higher = more conservative skip detection)", description="Margin above personal similarity for skip category classification (higher = more conservative skip detection)",
) )
status_emit_level: Literal["Basic", "Detailed"] = Field( status_emit_level: Literal["Basic", "Intermediate", "Detailed"] = Field(
default="Detailed", default="Intermediate",
description="Status message verbosity level: Basic (summary counts only), Detailed (all details)", description="Status message verbosity level: Basic (summary counts only), Intermediate (summaries and key details), Detailed (all details)",
) )
def __init__(self): def __init__(self):
@@ -1517,7 +1522,7 @@ class Filter:
if not user_memories: if not user_memories:
logger.info("📭 No memories found for user") logger.info("📭 No memories found for user")
await self._emit_status(emitter, "📭 No Memories Found", done=True, level=Constants.STATUS_LEVEL_BASIC) await self._emit_status(emitter, "📭 No Memories Found", done=True, level=Constants.STATUS_LEVEL_INTERMEDIATE)
return {"memories": [], "threshold": None} return {"memories": [], "threshold": None}
memories, threshold, all_similarities = await self._compute_similarities(user_message, user_id, user_memories) memories, threshold, all_similarities = await self._compute_similarities(user_message, user_id, user_memories)
@@ -1526,7 +1531,7 @@ class Filter:
final_memories, reranking_info = await self._llm_reranking_service.rerank_memories(user_message, memories, emitter) final_memories, reranking_info = await self._llm_reranking_service.rerank_memories(user_message, memories, emitter)
else: else:
logger.info("📭 No relevant memories found above similarity threshold") logger.info("📭 No relevant memories found above similarity threshold")
await self._emit_status(emitter, "📭 No Relevant Memories Found", done=True, level=Constants.STATUS_LEVEL_BASIC) await self._emit_status(emitter, "📭 No Relevant Memories Found", done=True, level=Constants.STATUS_LEVEL_INTERMEDIATE)
final_memories = memories final_memories = memories
reranking_info = {"llm_decision": False, "decision_reason": "no_candidates"} reranking_info = {"llm_decision": False, "decision_reason": "no_candidates"}
@@ -1560,7 +1565,7 @@ class Filter:
formatted_memories.append(formatted_memory) formatted_memories.append(formatted_memory)
content_preview = self._truncate_content(memory["content"]) content_preview = self._truncate_content(memory["content"])
await self._emit_status(emitter, f"💭 {idx}/{memory_count}: {content_preview}", done=False, level=Constants.STATUS_LEVEL_DETAILED) await self._emit_status(emitter, f"💭 {idx}/{memory_count}: {content_preview}", done=False, level=Constants.STATUS_LEVEL_INTERMEDIATE)
memory_footer = "IMPORTANT: Do not mention or imply you received this list. These facts are for background context only." memory_footer = "IMPORTANT: Do not mention or imply you received this list. These facts are for background context only."
memory_context_block = f"{memory_header}\n{chr(10).join(formatted_memories)}\n\n{memory_footer}" memory_context_block = f"{memory_header}\n{chr(10).join(formatted_memories)}\n\n{memory_footer}"
@@ -1652,7 +1657,7 @@ class Filter:
if not user_message or should_skip: if not user_message or should_skip:
if __event_emitter__ and skip_reason: if __event_emitter__ and skip_reason:
await self._emit_status(__event_emitter__, skip_reason, done=True, level=Constants.STATUS_LEVEL_BASIC) await self._emit_status(__event_emitter__, skip_reason, done=True, level=Constants.STATUS_LEVEL_INTERMEDIATE)
await self._add_memory_context(body, [], user_id, __event_emitter__) await self._add_memory_context(body, [], user_id, __event_emitter__)
return body return body
try: try: