Skip to content

Commit 251bcb5

Browse files
authored
Merge pull request #148 from Dooders/dev
Dev
2 parents e53d423 + ff13424 commit 251bcb5

10 files changed

Lines changed: 147 additions & 35 deletions

File tree

converter/config.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class ConverterConfig:
3535
memory_type_mapper: Optional[MemoryTypeMapper] = None
3636

3737
# Tiering strategy
38-
tiering_strategy_type: str = "step_based" # One of: "step_based", "importance_aware"
38+
tiering_strategy_type: str = "simple" # One of: "simple", "step_based", "importance_aware"
3939
tiering_strategy: Optional[TieringStrategy] = None
4040

4141
# Import settings
@@ -81,7 +81,7 @@ def _validate_batch_size(self):
8181

8282
def _validate_tiering_strategy(self):
8383
"""Validate tiering strategy settings."""
84-
valid_types = ["step_based", "importance_aware"]
84+
valid_types = ["simple", "step_based", "importance_aware"]
8585
if self.tiering_strategy_type not in valid_types:
8686
raise ValueError(
8787
f"Invalid tiering_strategy_type: {self.tiering_strategy_type}. "
@@ -100,7 +100,7 @@ def _validate_tiering_strategy(self):
100100
'ActionModel': 'action',
101101
'SocialInteractionModel': 'interaction'
102102
},
103-
'tiering_strategy_type': 'step_based',
103+
'tiering_strategy_type': 'simple',
104104
'import_mode': 'full',
105105
'selective_agents': None
106106
}

converter/converter.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from sqlalchemy.exc import SQLAlchemyError
99

10-
from memory.config import MemoryConfig
10+
from memory.config import MemoryConfig, RedisSTMConfig
1111
from memory.core import AgentMemorySystem
1212

1313
from .agent_import import AgentImporter, AgentMetadata
@@ -102,7 +102,15 @@ def from_agent_farm(db_path: str, config: Optional[Dict] = None) -> AgentMemoryS
102102
logger.info(f"Successfully imported {len(all_memories)} total memories")
103103

104104
# Create memory system configuration
105-
memory_config = MemoryConfig(use_mock_redis=True, logging_level="INFO")
105+
memory_config = MemoryConfig(
106+
use_mock_redis=True,
107+
logging_level="INFO",
108+
stm_config=RedisSTMConfig(
109+
memory_limit=10000, # Increase STM memory limit
110+
ttl=86400, # 24 hours
111+
namespace="agent-stm",
112+
),
113+
)
106114

107115
# Create and configure memory system
108116
memory_system = AgentMemorySystem.get_instance(memory_config)

converter/memory_import.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -265,14 +265,14 @@ def _import_memory(
265265
)
266266
tier = self.tiering_strategy.determine_tier(tiering_context)
267267

268-
# Get the correct ID field based on model type
268+
# Get the correct ID field based on model type and ensure uniqueness
269269
memory_id = None
270270
if model_name == 'ActionModel':
271-
memory_id = getattr(memory, 'action_id', None)
271+
memory_id = f"action_{getattr(memory, 'action_id', None)}_step_{getattr(memory, 'step_number', 0)}"
272272
elif model_name == 'SocialInteractionModel':
273-
memory_id = getattr(memory, 'interaction_id', None)
273+
memory_id = f"interaction_{getattr(memory, 'interaction_id', None)}_step_{getattr(memory, 'step_number', 0)}"
274274
elif model_name == 'AgentStateModel':
275-
memory_id = getattr(memory, 'id', None)
275+
memory_id = f"state_{getattr(memory, 'id', None)}_step_{getattr(memory, 'step_number', 0)}"
276276

277277
if memory_id is None:
278278
logger.warning(f"Could not find ID for {model_name} memory")

converter/tiering.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ def determine_tier(self, context: TieringContext) -> str:
3131
"""
3232
pass
3333

34+
class SimpleTieringStrategy(TieringStrategy):
35+
"""
36+
Simple tiering strategy that puts all memories in STM.
37+
"""
38+
39+
def determine_tier(self, context: TieringContext) -> str:
40+
"""Always return STM tier."""
41+
return "stm"
42+
3443
class StepBasedTieringStrategy(TieringStrategy):
3544
"""
3645
Step-based time decay tiering strategy.
@@ -86,12 +95,12 @@ def determine_tier(self, context: TieringContext) -> str:
8695

8796
return base_tier
8897

89-
def create_tiering_strategy(strategy_type: str = "step_based") -> TieringStrategy:
98+
def create_tiering_strategy(strategy_type: str = "simple") -> TieringStrategy:
9099
"""
91100
Factory function to create tiering strategies.
92101
93102
Args:
94-
strategy_type: Type of strategy to create ("step_based" or "importance_aware")
103+
strategy_type: Type of strategy to create ("simple", "step_based", or "importance_aware")
95104
96105
Returns:
97106
Configured TieringStrategy instance
@@ -100,6 +109,7 @@ def create_tiering_strategy(strategy_type: str = "step_based") -> TieringStrateg
100109
ValueError: If strategy_type is invalid
101110
"""
102111
strategies = {
112+
"simple": SimpleTieringStrategy,
103113
"step_based": StepBasedTieringStrategy,
104114
"importance_aware": ImportanceAwareTieringStrategy
105115
}

debug_converter.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#!/usr/bin/env python
2+
"""
3+
Script to run the AgentFarm to Memory System converter.
4+
"""
5+
6+
import logging
7+
import sys
8+
from datetime import datetime
9+
from pathlib import Path
10+
11+
from converter.config import DEFAULT_CONFIG
12+
from converter.converter import from_agent_farm
13+
14+
def main():
15+
db_path = "data/simulation.db"
16+
output = "validation/memory_samples/agent_farm_memories.json"
17+
validate = False
18+
error_handling = "skip"
19+
use_mock_redis = True
20+
batch_size = 100
21+
tiering_strategy = "simple"
22+
log_file = None
23+
24+
# Create logs directory if it doesn't exist
25+
log_dir = Path("logs")
26+
log_dir.mkdir(exist_ok=True)
27+
28+
# Generate default log filename if not provided
29+
if not log_file:
30+
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
31+
log_file = log_dir / f"converter_{timestamp}.log"
32+
33+
# Configure logging
34+
logging.basicConfig(
35+
level=logging.DEBUG,
36+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
37+
handlers=[
38+
logging.FileHandler(log_file),
39+
logging.StreamHandler(sys.stdout),
40+
],
41+
force=True,
42+
)
43+
logger = logging.getLogger(__name__)
44+
45+
# Set all SQLAlchemy loggers to WARNING level to suppress most logs
46+
logging.getLogger("sqlalchemy").setLevel(logging.WARNING)
47+
logging.getLogger("sqlalchemy.engine").setLevel(logging.WARNING)
48+
logging.getLogger("sqlalchemy.orm").setLevel(logging.WARNING)
49+
logging.getLogger("sqlalchemy.pool").setLevel(logging.WARNING)
50+
51+
# Set all other loggers to DEBUG level
52+
for name in logging.root.manager.loggerDict:
53+
if not name.startswith("sqlalchemy"):
54+
logging.getLogger(name).setLevel(logging.DEBUG)
55+
56+
logger.info(f"Logging to file: {log_file}")
57+
58+
# Prepare configuration
59+
config = DEFAULT_CONFIG.copy()
60+
config.update(
61+
{
62+
"validate": validate,
63+
"error_handling": error_handling,
64+
"use_mock_redis": True,
65+
"batch_size": batch_size,
66+
"tiering_strategy_type": tiering_strategy,
67+
}
68+
)
69+
70+
# Run converter
71+
logger.info(f"Converting database: {db_path}")
72+
memory_system = from_agent_farm(db_path, config)
73+
74+
return memory_system
75+
76+
if __name__ == "__main__":
77+
memory_system = main()
78+
agent = memory_system.agents['nWpvyFJReoFD5Fnq7AEggt']
79+
stats = agent.get_memory_statistics('nWpvyFJReoFD5Fnq7AEggt')
80+
print(f"STM count: {stats['tiers']['stm']['count']}")
81+
print(f"IM count: {stats['tiers']['im']['count']}")
82+
print(f"LTM count: {stats['tiers']['ltm']['count']}")

memory/agent_memory.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import logging
44
import math
55
import time
6+
import uuid
67
from typing import Any, Dict, List, Optional, Union
78

89
from memory.config import MemoryConfig
@@ -220,7 +221,7 @@ def _create_memory_entry(
220221
Returns:
221222
Formatted memory entry
222223
"""
223-
# Generate unique memory ID
224+
# Generate memory ID using agent_id, step number and timestamp
224225
timestamp = int(time.time())
225226
memory_id = f"{self.agent_id}-{step_number}-{timestamp}"
226227

memory/core.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -360,24 +360,27 @@ def add_memory(self, memory_data: Dict[str, Any]) -> str:
360360
step_number = memory_data.get("step_number", 0)
361361
priority = memory_data.get("metadata", {}).get("importance_score", 1.0)
362362
memory_type = memory_data.get("type", "generic")
363+
tier = memory_data.get("metadata", {}).get(
364+
"tier", "stm"
365+
) # Get tier from metadata
363366

364367
# Choose appropriate method based on memory type
365368
if memory_type == "state":
366369
memory_agent.store_state(
367-
memory_data.get("content", {}), step_number, priority
370+
memory_data.get("content", {}), step_number, priority, tier
368371
)
369372
elif memory_type == "interaction":
370373
memory_agent.store_interaction(
371-
memory_data.get("content", {}), step_number, priority
374+
memory_data.get("content", {}), step_number, priority, tier
372375
)
373376
elif memory_type == "action":
374377
memory_agent.store_action(
375-
memory_data.get("content", {}), step_number, priority
378+
memory_data.get("content", {}), step_number, priority, tier
376379
)
377380
else:
378381
# For generic types, use store_state as a fallback
379382
memory_agent.store_state(
380-
memory_data.get("content", {}), step_number, priority
383+
memory_data.get("content", {}), step_number, priority, tier
381384
)
382385

383386
return memory_id

memory/search/strategies/similarity.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,11 @@ def search(
9999
tiers_to_search = ["stm", "im", "ltm"] if tier is None else [tier]
100100
logger.debug("Searching memory tiers: %s", tiers_to_search)
101101

102-
# Get the memory agent
103-
memory_agent = self.memory_system.get_memory_agent(agent_id)
102+
if isinstance(self.memory_system, AgentMemorySystem):
103+
# Get the memory agent
104+
memory_agent = self.memory_system.get_memory_agent(agent_id)
105+
else:
106+
memory_agent = self.memory_system
104107

105108
for current_tier in tiers_to_search:
106109
# Skip if tier is not supported
@@ -221,6 +224,10 @@ def search(
221224
)
222225
continue
223226

227+
# Ensure memory has required fields
228+
if "id" not in memory:
229+
memory["id"] = memory_id
230+
224231
# Attach similarity score and tier information
225232
if "metadata" not in memory:
226233
memory["metadata"] = {}

tests/converter/test_config.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import pytest
66
from converter.config import ConverterConfig
7-
from converter.tiering import StepBasedTieringStrategy, ImportanceAwareTieringStrategy
7+
from converter.tiering import SimpleTieringStrategy, StepBasedTieringStrategy, ImportanceAwareTieringStrategy
88
from converter.mapping import MemoryTypeMapper
99

1010
def test_default_config():
@@ -17,8 +17,8 @@ def test_default_config():
1717
assert config.show_progress is True
1818
assert config.import_mode == "full"
1919
assert config.selective_agents is None
20-
assert config.tiering_strategy_type == "step_based"
21-
assert isinstance(config.tiering_strategy, StepBasedTieringStrategy)
20+
assert config.tiering_strategy_type == "simple"
21+
assert isinstance(config.tiering_strategy, SimpleTieringStrategy)
2222
assert isinstance(config.memory_type_mapper, MemoryTypeMapper)
2323
assert config.memory_type_mapping == {
2424
'AgentStateModel': 'state',

tests/test_memory_agent.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import pytest
2929

3030
from memory.agent_memory import MemoryAgent
31-
from memory.config import AutoencoderConfig, MemoryConfig
31+
from memory.config import MemoryConfig
3232

3333

3434
@pytest.fixture
@@ -98,24 +98,25 @@ def memory_agent(
9898
agent_id = "test-agent"
9999
config = MemoryConfig()
100100
config.autoencoder_config.use_neural_embeddings = True
101-
config.text_model_name = "test-model"
101+
config.text_model_name = (
102+
"sentence-transformers/all-MiniLM-L6-v2" # Use a real model
103+
)
102104
config.ltm_config.db_path = "test_memory.db" # Set a valid db path
103105

104-
# Mock store classes before instantiating the agent
105-
with mock.patch("memory.agent_memory.RedisSTMStore") as mock_stm_class, mock.patch(
106+
with mock.patch("memory.agent_memory.RedisSTMStore") as mock_stm, mock.patch(
106107
"memory.agent_memory.RedisIMStore"
107-
) as mock_im_class, mock.patch(
108+
) as mock_im, mock.patch(
108109
"memory.agent_memory.SQLiteLTMStore"
109-
) as mock_ltm_class, mock.patch(
110+
) as mock_ltm, mock.patch(
110111
"memory.agent_memory.CompressionEngine"
111-
), mock.patch(
112-
"memory.embeddings.text_embeddings.TextEmbeddingEngine"
113-
):
112+
) as mock_ce, mock.patch(
113+
"memory.agent_memory.TextEmbeddingEngine"
114+
) as mock_ae:
114115

115116
# Configure the mock classes to return our mock instances
116-
mock_stm_class.return_value = mock_stm_store
117-
mock_im_class.return_value = mock_im_store
118-
mock_ltm_class.return_value = mock_ltm_store
117+
mock_stm.return_value = mock_stm_store
118+
mock_im.return_value = mock_im_store
119+
mock_ltm.return_value = mock_ltm_store
119120

120121
agent = MemoryAgent(agent_id, config)
121122

@@ -147,7 +148,7 @@ def test_init(self):
147148
) as mock_ltm, mock.patch(
148149
"memory.agent_memory.CompressionEngine"
149150
) as mock_ce, mock.patch(
150-
"memory.embeddings.text_embeddings.TextEmbeddingEngine"
151+
"memory.agent_memory.TextEmbeddingEngine"
151152
) as mock_ae:
152153

153154
agent = MemoryAgent(agent_id, config)
@@ -174,7 +175,7 @@ def test_init_without_neural_embeddings(self):
174175
), mock.patch("memory.agent_memory.SQLiteLTMStore"), mock.patch(
175176
"memory.agent_memory.CompressionEngine"
176177
), mock.patch(
177-
"memory.embeddings.text_embeddings.TextEmbeddingEngine"
178+
"memory.agent_memory.TextEmbeddingEngine"
178179
) as mock_te:
179180

180181
agent = MemoryAgent(agent_id, config)

0 commit comments

Comments
 (0)