mirror of
https://github.com/mtayfur/openwebui-memory-system.git
synced 2026-01-22 06:51:01 +01:00
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:
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user