ReMe/reme_ai/retrieve/personal/print_memory_op.py

149 lines
4.6 KiB
Python

"""Memory printing operation for personal memories.
This module provides functionality to format and print memories in various formats
for display or output purposes.
"""
from typing import List
from flowllm.core.context import C
from flowllm.core.op import BaseAsyncOp
from loguru import logger
from reme_ai.schema.memory import BaseMemory
@C.register_op()
class PrintMemoryOp(BaseAsyncOp):
"""
Formats the memories to print.
"""
file_path: str = __file__
async def async_execute(self):
"""
Executes the primary function, it involves:
1. Fetches the memories.
2. Formats them for printing.
3. Set the formatted string back into the context
"""
# Get memory list from context
memory_list: List[BaseMemory] = self.context.response.metadata.get("memory_list", [])
if not memory_list:
logger.info("No memories to print")
self.context.response.answer = "No memories found."
return
logger.info(f"Formatting {len(memory_list)} memories for printing")
# Format memories for printing
formatted_memories = self._format_memories_for_print(memory_list)
# Store result in context
self.context.response.answer = formatted_memories
logger.info(f"Formatted memories: {formatted_memories}")
@staticmethod
def _format_memories_for_print(memories: List[BaseMemory]) -> str:
"""
Format memories for printing.
Args:
memories: List of memory objects to format
Returns:
Formatted string representation of memories
"""
if not memories:
return "No memories available."
formatted_memories = []
for i, memory in enumerate(memories, 1):
memory_text = f"Memory {i}:\n"
memory_text += f" When to use: {memory.when_to_use}\n"
memory_text += f" Content: {memory.content}\n"
# Add additional metadata if available
if hasattr(memory, "metadata") and memory.metadata:
metadata_items = []
for key, value in memory.metadata.items():
if key not in ["when_to_use", "content"]:
metadata_items.append(f"{key}: {value}")
if metadata_items:
memory_text += f" Metadata: {', '.join(metadata_items)}\n"
formatted_memories.append(memory_text)
return "\n".join(formatted_memories)
@staticmethod
def format_memories_for_output(memories: List) -> str:
"""
Format memory list for output string.
Args:
memories: List of memory objects
Returns:
Formatted string
"""
if not memories:
return ""
formatted_parts = []
for i, memory in enumerate(memories, 1):
when_to_use = getattr(memory, "when_to_use", "") or memory.get("when_to_use", "")
content = getattr(memory, "content", "") or memory.get("content", "")
part = f"Memory {i}:\n"
if when_to_use:
part += f"When to use: {when_to_use}\n"
if content:
part += f"Content: {content}\n"
formatted_parts.append(part)
return "\n".join(formatted_parts)
@staticmethod
def format_memories_for_simple_output(memories: List) -> str:
"""
Format memory list for simple flow output.
Args:
memories: List of memory objects
Returns:
Formatted string suitable for response.answer
"""
if not memories:
return "No relevant memories found."
content_parts = ["Previous Memory"]
for memory in memories:
# Safely get field values
when_to_use = getattr(memory, "when_to_use", "") or memory.get("when_to_use", "")
content = getattr(memory, "content", "") or memory.get("content", "")
# Skip memories with empty content
if not content:
continue
# Format individual memory
memory_text = f"- when_to_use: {when_to_use}\n content: {content}"
content_parts.append(memory_text)
# If no valid memories, return empty message
if len(content_parts) == 1: # Only title
return "No relevant memories with valid content found."
content_parts.append(
"\nPlease consider the helpful parts from these in answering the question, "
"to make the response more comprehensive and substantial.",
)
return "\n".join(content_parts)