get rid of global memory

This commit is contained in:
AI Christianson 2025-03-04 21:25:37 -05:00
parent 5bd8c76a22
commit c9f3f37ca3
10 changed files with 6 additions and 108 deletions

View File

@ -81,7 +81,6 @@ from ra_aid.prompts.chat_prompts import CHAT_PROMPT
from ra_aid.prompts.web_research_prompts import WEB_RESEARCH_PROMPT_SECTION_CHAT
from ra_aid.tool_configs import get_chat_tools, set_modification_tools
from ra_aid.tools.human import ask_human
from ra_aid.tools.memory import get_memory_value
logger = get_logger(__name__)

View File

@ -94,7 +94,6 @@ from ra_aid.model_formatters import format_key_facts_dict
from ra_aid.model_formatters.key_snippets_formatter import format_key_snippets_dict
from ra_aid.model_formatters.research_notes_formatter import format_research_notes_dict
from ra_aid.tools.memory import (
get_memory_value,
get_related_files,
log_work_event,
)

View File

@ -9,7 +9,6 @@ from .memory import (
emit_key_snippet,
emit_related_files,
emit_research_notes,
get_memory_value,
plan_implementation_completed,
task_completed,
)
@ -31,7 +30,6 @@ __all__ = [
"emit_related_files",
"emit_research_notes",
"fuzzy_find_project_files",
"get_memory_value",
"list_directory_tree",
"read_file_tool",
"run_programming_task",

View File

@ -29,7 +29,7 @@ from ra_aid.model_formatters.research_notes_formatter import format_research_not
from ..console import print_task_header
from ..llm import initialize_llm
from .human import ask_human
from .memory import get_memory_value, get_related_files, get_work_log
from .memory import get_related_files, get_work_log
ResearchResult = Dict[str, Union[str, bool, Dict[int, Any], List[Any], None]]

View File

@ -18,7 +18,6 @@ from ..llm import initialize_expert_llm
from ..model_formatters import format_key_facts_dict
from ..model_formatters.key_snippets_formatter import format_key_snippets_dict
from ..model_formatters.research_notes_formatter import format_research_notes_dict
from .memory import get_memory_value
console = Console()
_model = None

View File

@ -40,9 +40,6 @@ from ra_aid.database.repositories.key_fact_repository import get_key_fact_reposi
# Import the related files repository
from ra_aid.database.repositories.related_files_repository import get_related_files_repository
# Global memory store
_global_memory: Dict[str, Any] = {}
@tool("emit_research_notes")
def emit_research_notes(notes: str) -> str:
@ -475,62 +472,4 @@ def deregister_related_files(file_ids: List[int]) -> str:
)
results.append(success_msg)
return "Files noted."
def get_memory_value(key: str) -> str:
"""
Get a value from global memory.
Note: Key facts and key snippets are handled by their respective repository and formatter modules,
and should be accessed directly using those instead of through this function.
Different memory types return different formats:
- For work_log: Returns formatted markdown with timestamps and events
- For research_notes: Returns formatted markdown from repository
- For other types: Returns newline-separated list of values
Args:
key: The key to get from memory
Returns:
String representation of the memory values
"""
if key == "work_log":
# Use the repository to get the formatted work log
try:
repo = get_work_log_repository()
return repo.format_work_log()
except RuntimeError as e:
logger.error(f"Failed to access work log repository: {str(e)}")
return ""
if key == "research_notes":
# DEPRECATED: This method of accessing research notes is deprecated.
# Use direct repository access instead:
# from ra_aid.database.repositories.research_note_repository import get_research_note_repository
# from ra_aid.model_formatters.research_notes_formatter import format_research_notes_dict
# repository = get_research_note_repository()
# notes_dict = repository.get_notes_dict()
# formatted_notes = format_research_notes_dict(notes_dict)
logger.warning("DEPRECATED: Accessing research notes via get_memory_value() is deprecated. "
"Use direct repository access with get_research_note_repository() instead.")
try:
# Import required modules for research notes
from ra_aid.database.repositories.research_note_repository import get_research_note_repository
from ra_aid.model_formatters.research_notes_formatter import format_research_notes_dict
# Get notes from repository and format them
repository = get_research_note_repository()
notes_dict = repository.get_notes_dict()
return format_research_notes_dict(notes_dict)
except RuntimeError as e:
logger.error(f"Failed to access research note repository: {str(e)}")
return ""
except Exception as e:
logger.error(f"Error accessing research notes: {str(e)}")
return ""
# For other types (lists), join with newlines
values = _global_memory.get(key, [])
return "\n".join(str(v) for v in values)
return "Files noted."

View File

@ -8,7 +8,7 @@ from rich.prompt import Prompt
from ra_aid.console.cowboy_messages import get_cowboy_message
from ra_aid.proc.interactive import run_interactive_command
from ra_aid.text.processing import truncate_output
from ra_aid.tools.memory import _global_memory, log_work_event
from ra_aid.tools.memory import log_work_event
from ra_aid.database.repositories.config_repository import get_config_repository
console = Console()

View File

@ -5,7 +5,6 @@ from unittest.mock import patch, MagicMock
from ra_aid.__main__ import parse_arguments
from ra_aid.config import DEFAULT_RECURSION_LIMIT
from ra_aid.tools.memory import _global_memory
from ra_aid.database.repositories.work_log_repository import WorkLogEntry
from ra_aid.database.repositories.config_repository import ConfigRepositoryManager, get_config_repository
@ -49,9 +48,6 @@ def mock_config_repository():
@pytest.fixture
def mock_dependencies(monkeypatch):
"""Mock all dependencies needed for main()."""
# Initialize global memory
_global_memory.clear()
# Mock dependencies that interact with external systems
monkeypatch.setattr("ra_aid.__main__.check_dependencies", lambda: None)
monkeypatch.setattr("ra_aid.__main__.validate_environment", lambda args: (True, [], True, []))

View File

@ -10,7 +10,6 @@ from ra_aid.tools.agent import (
request_implementation,
request_research_and_implementation,
)
from ra_aid.tools.memory import _global_memory
from ra_aid.database.repositories.related_files_repository import get_related_files_repository
from ra_aid.database.repositories.work_log_repository import get_work_log_repository, WorkLogEntry
from ra_aid.database.repositories.config_repository import get_config_repository
@ -18,8 +17,7 @@ from ra_aid.database.repositories.config_repository import get_config_repository
@pytest.fixture
def reset_memory():
"""Reset global memory before each test"""
# No longer need to reset work_log in global memory
"""Fixture for test initialization (kept for backward compatibility)"""
yield
@ -126,7 +124,6 @@ def mock_functions():
patch('ra_aid.tools.agent.format_key_snippets_dict') as mock_snippet_formatter, \
patch('ra_aid.tools.agent.initialize_llm') as mock_llm, \
patch('ra_aid.tools.agent.get_related_files') as mock_get_files, \
patch('ra_aid.tools.agent.get_memory_value') as mock_get_memory, \
patch('ra_aid.tools.agent.get_work_log') as mock_get_work_log, \
patch('ra_aid.tools.agent.reset_completion_flags') as mock_reset, \
patch('ra_aid.tools.agent.get_completion_message') as mock_get_completion:
@ -138,7 +135,6 @@ def mock_functions():
mock_snippet_formatter.return_value = "Formatted snippets"
mock_llm.return_value = MagicMock()
mock_get_files.return_value = ["file1.py", "file2.py"]
mock_get_memory.return_value = "Test memory value"
mock_get_work_log.return_value = "Test work log"
mock_get_completion.return_value = "Task completed"
@ -150,7 +146,6 @@ def mock_functions():
'format_key_snippets_dict': mock_snippet_formatter,
'initialize_llm': mock_llm,
'get_related_files': mock_get_files,
'get_memory_value': mock_get_memory,
'get_work_log': mock_get_work_log,
'reset_completion_flags': mock_reset,
'get_completion_message': mock_get_completion
@ -175,10 +170,6 @@ def test_request_research_uses_key_fact_repository(reset_memory, mock_functions)
# Verify formatted facts are used in response
assert result["key_facts"] == "Formatted facts"
# Verify get_memory_value is not called with "key_facts"
for call in mock_functions['get_memory_value'].call_args_list:
assert call[0][0] != "key_facts"
def test_request_research_max_depth(reset_memory, mock_functions):
@ -201,10 +192,6 @@ def test_request_research_max_depth(reset_memory, mock_functions):
# Verify formatted facts are used in response
assert result["key_facts"] == "Formatted facts"
# Verify get_memory_value is not called with "key_facts"
for call in mock_functions['get_memory_value'].call_args_list:
assert call[0][0] != "key_facts"
def test_request_research_and_implementation_uses_key_fact_repository(reset_memory, mock_functions):
@ -225,10 +212,6 @@ def test_request_research_and_implementation_uses_key_fact_repository(reset_memo
# Verify formatted facts are used in response
assert result["key_facts"] == "Formatted facts"
# Verify get_memory_value is not called with "key_facts"
for call in mock_functions['get_memory_value'].call_args_list:
assert call[0][0] != "key_facts"
def test_request_implementation_uses_key_fact_repository(reset_memory, mock_functions):
@ -253,9 +236,6 @@ def test_request_implementation_uses_key_fact_repository(reset_memory, mock_func
def test_request_task_implementation_uses_key_fact_repository(reset_memory, mock_functions):
"""Test that request_task_implementation uses KeyFactRepository correctly."""
# Set up _global_memory with required values (without tasks)
_global_memory["base_task"] = "Base task"
# Mock running the implementation agent
with patch('ra_aid.agent_utils.run_task_implementation_agent'):
# Call the function

View File

@ -7,12 +7,10 @@ from unittest.mock import patch, MagicMock, ANY
from ra_aid.agents.key_snippets_gc_agent import delete_key_snippets
from ra_aid.tools.memory import (
_global_memory,
deregister_related_files,
emit_key_facts,
emit_key_snippet,
emit_related_files,
get_memory_value,
get_related_files,
get_work_log,
log_work_event,
@ -29,8 +27,7 @@ from ra_aid.database.models import KeyFact
@pytest.fixture
def reset_memory():
"""Reset global memory before each test"""
# No longer need to reset work_log in global memory
"""Fixture for test initialization (kept for backward compatibility)"""
yield
@ -274,15 +271,6 @@ def test_emit_key_facts_single_fact(reset_memory, mock_repository):
mock_repository.return_value.create.assert_called_once_with("First fact", human_input_id=ANY)
def test_get_memory_value_other_types(reset_memory):
"""Test get_memory_value remains compatible with other memory types"""
# Test with non-existent key
assert get_memory_value("nonexistent") == ""
# Test research_notes returns empty string when no repository is available
assert get_memory_value("research_notes") == ""
def test_log_work_event(reset_memory, mock_work_log_repository):
"""Test logging work events with timestamps"""
# Log some events
@ -338,7 +326,7 @@ def test_reset_work_log(reset_memory, mock_work_log_repository):
# Verify clear was called
mock_work_log_repository.return_value.clear.assert_called_once()
# Setup mock for get_memory_value test
# Setup mock for empty log
mock_work_log_repository.return_value.format_work_log.return_value = "No work log entries"
# Verify empty log directly via repository