Skip to content

Commit d4960bd

Browse files
authored
Merge pull request #138 from Dooders/agent-farm-converter
Agent farm converter
2 parents e9519c3 + bba494a commit d4960bd

22 files changed

+2218
-90
lines changed

TEST_CHANGELOG.md

Lines changed: 0 additions & 40 deletions
This file was deleted.

converter/__init__.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""
2+
AgentFarm DB to Memory System Converter
3+
4+
This module provides functionality to convert data from an AgentFarm SQLite database
5+
into a memory system, handling the import of agents and their associated memories.
6+
"""
7+
8+
__version__ = "0.1.0"
9+
10+
from .config import DEFAULT_CONFIG
11+
from .converter import from_agent_farm
12+
13+
__all__ = ["from_agent_farm", "DEFAULT_CONFIG"]

converter/agent_import.py

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
"""
2+
Agent import system for the AgentFarm DB to Memory System converter.
3+
"""
4+
5+
import logging
6+
from dataclasses import dataclass
7+
from typing import Any, Dict, List, Optional
8+
9+
from .config import ConverterConfig
10+
from .db import DatabaseManager
11+
12+
logger = logging.getLogger(__name__)
13+
14+
15+
@dataclass
16+
class AgentMetadata:
17+
"""Metadata for an imported agent."""
18+
19+
agent_id: str
20+
name: str
21+
metadata: Dict[str, Any]
22+
created_at: str
23+
updated_at: str
24+
25+
26+
class AgentImporter:
27+
"""
28+
Handles the import of agents from AgentFarm database to memory system.
29+
30+
This class manages the process of importing agents, including validation,
31+
metadata preservation, and error handling.
32+
"""
33+
34+
def __init__(self, db_manager: DatabaseManager, config: ConverterConfig):
35+
"""
36+
Initialize the agent importer.
37+
38+
Args:
39+
db_manager: Database manager instance
40+
config: Converter configuration
41+
"""
42+
self.db_manager = db_manager
43+
self.config = config
44+
45+
def import_agents(self) -> List[AgentMetadata]:
46+
"""
47+
Import agents from the database.
48+
49+
Returns:
50+
List of imported agent metadata
51+
52+
Raises:
53+
ValueError: If agent validation fails and error_handling is 'fail'
54+
"""
55+
agents = []
56+
with self.db_manager.session() as session:
57+
# Get agent query based on import mode
58+
query = self._get_agent_query(session)
59+
60+
# Process agents in batches
61+
for batch in self._batch_query(query):
62+
for agent in batch:
63+
try:
64+
agent_metadata = self._import_agent(agent)
65+
agents.append(agent_metadata)
66+
except Exception as e:
67+
self._handle_import_error(e, agent)
68+
69+
return agents
70+
71+
def _get_agent_query(self, session):
72+
"""Get the appropriate agent query based on import mode."""
73+
query = session.query(self.db_manager.AgentModel)
74+
75+
if self.config.import_mode == "incremental":
76+
# Add incremental import conditions
77+
pass
78+
79+
if self.config.selective_agents:
80+
query = query.filter(
81+
self.db_manager.AgentModel.agent_id.in_(self.config.selective_agents)
82+
)
83+
84+
return query
85+
86+
def _batch_query(self, query):
87+
"""Process query in batches."""
88+
offset = 0
89+
while True:
90+
batch = query.offset(offset).limit(self.config.batch_size).all()
91+
if not batch:
92+
break
93+
yield batch
94+
offset += self.config.batch_size
95+
96+
def _import_agent(self, agent) -> AgentMetadata:
97+
"""
98+
Import a single agent.
99+
100+
Args:
101+
agent: Agent model instance
102+
103+
Returns:
104+
AgentMetadata instance
105+
106+
Raises:
107+
ValueError: If agent validation fails
108+
"""
109+
# Validate agent
110+
if self.config.validate:
111+
self._validate_agent(agent)
112+
113+
# Create agent metadata
114+
metadata = AgentMetadata(
115+
agent_id=agent.agent_id,
116+
# Use agent_id as the name if agent doesn't have a name attribute
117+
name=getattr(agent, "name", f"Agent-{agent.agent_id}"),
118+
metadata=self._extract_agent_metadata(agent),
119+
created_at=str(agent.birth_time),
120+
updated_at=str(agent.death_time or agent.birth_time),
121+
)
122+
123+
return metadata
124+
125+
def _validate_agent(self, agent):
126+
"""
127+
Validate an agent.
128+
129+
Args:
130+
agent: Agent model instance
131+
132+
Raises:
133+
ValueError: If validation fails
134+
"""
135+
if not agent.agent_id:
136+
raise ValueError("Agent must have an ID")
137+
138+
def _extract_agent_metadata(self, agent) -> Dict[str, Any]:
139+
"""
140+
Extract metadata from an agent.
141+
142+
Args:
143+
agent: Agent model instance
144+
145+
Returns:
146+
Dictionary of agent metadata
147+
"""
148+
return {
149+
"type": agent.agent_type,
150+
"position": {"x": agent.position_x, "y": agent.position_y},
151+
"initial_resources": agent.initial_resources,
152+
"starting_health": agent.starting_health,
153+
"starvation_threshold": agent.starvation_threshold,
154+
"genome_id": agent.genome_id,
155+
"generation": agent.generation,
156+
"action_weights": agent.action_weights,
157+
}
158+
159+
def _handle_import_error(self, error: Exception, agent: Any):
160+
"""
161+
Handle agent import error based on configuration.
162+
163+
Args:
164+
error: The error that occurred
165+
agent: The agent that caused the error
166+
"""
167+
error_msg = f"Error importing agent {agent.agent_id}: {str(error)}"
168+
169+
if self.config.error_handling == "fail":
170+
raise ValueError(error_msg)
171+
elif self.config.error_handling == "log":
172+
logger.error(error_msg)
173+
# Skip mode just continues without raising or logging

converter/config.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
"""
2+
Configuration system for the AgentFarm DB to Memory System converter.
3+
"""
4+
5+
import logging
6+
from dataclasses import dataclass, field
7+
from typing import Dict, Optional, List, Union
8+
9+
from .tiering import TieringStrategy, create_tiering_strategy
10+
from .mapping import MemoryTypeMapper
11+
12+
logger = logging.getLogger(__name__)
13+
14+
@dataclass
15+
class ConverterConfig:
16+
"""Configuration for the AgentFarm DB to Memory System converter."""
17+
18+
# Redis configuration
19+
use_mock_redis: bool = True
20+
21+
# Validation settings
22+
validate: bool = True
23+
error_handling: str = "skip" # One of: "skip", "fail", "log"
24+
25+
# Processing settings
26+
batch_size: int = 100
27+
show_progress: bool = True
28+
29+
# Memory type mapping
30+
memory_type_mapping: Dict[str, str] = field(default_factory=lambda: {
31+
'AgentStateModel': 'state',
32+
'ActionModel': 'action',
33+
'SocialInteractionModel': 'interaction'
34+
})
35+
memory_type_mapper: Optional[MemoryTypeMapper] = None
36+
37+
# Tiering strategy
38+
tiering_strategy_type: str = "step_based" # One of: "step_based", "importance_aware"
39+
tiering_strategy: Optional[TieringStrategy] = None
40+
41+
# Import settings
42+
import_mode: str = "full" # One of: "full", "incremental"
43+
selective_agents: Optional[List[int]] = None
44+
total_steps: Optional[int] = None # Total number of steps in the simulation
45+
46+
def __post_init__(self):
47+
"""Validate configuration after initialization."""
48+
self._validate_error_handling()
49+
self._validate_import_mode()
50+
self._validate_batch_size()
51+
self._validate_tiering_strategy()
52+
53+
# Initialize memory type mapper
54+
if self.memory_type_mapper is None:
55+
self.memory_type_mapper = MemoryTypeMapper(mapping=self.memory_type_mapping)
56+
57+
# Initialize tiering strategy if not provided
58+
if self.tiering_strategy is None:
59+
self.tiering_strategy = create_tiering_strategy(self.tiering_strategy_type)
60+
61+
def _validate_error_handling(self):
62+
"""Validate error handling mode."""
63+
if self.error_handling not in ["skip", "fail", "log"]:
64+
raise ValueError(
65+
f"Invalid error_handling mode: {self.error_handling}. "
66+
"Must be one of: skip, fail, log"
67+
)
68+
69+
def _validate_import_mode(self):
70+
"""Validate import mode."""
71+
if self.import_mode not in ["full", "incremental"]:
72+
raise ValueError(
73+
f"Invalid import_mode: {self.import_mode}. "
74+
"Must be one of: full, incremental"
75+
)
76+
77+
def _validate_batch_size(self):
78+
"""Validate batch size."""
79+
if self.batch_size < 1:
80+
raise ValueError("batch_size must be greater than 0")
81+
82+
def _validate_tiering_strategy(self):
83+
"""Validate tiering strategy settings."""
84+
valid_types = ["step_based", "importance_aware"]
85+
if self.tiering_strategy_type not in valid_types:
86+
raise ValueError(
87+
f"Invalid tiering_strategy_type: {self.tiering_strategy_type}. "
88+
f"Must be one of: {valid_types}"
89+
)
90+
91+
# Default configuration
92+
DEFAULT_CONFIG = {
93+
'use_mock_redis': True,
94+
'validate': True,
95+
'error_handling': 'skip',
96+
'batch_size': 100,
97+
'show_progress': True,
98+
'memory_type_mapping': {
99+
'AgentStateModel': 'state',
100+
'ActionModel': 'action',
101+
'SocialInteractionModel': 'interaction'
102+
},
103+
'tiering_strategy_type': 'step_based',
104+
'import_mode': 'full',
105+
'selective_agents': None
106+
}

0 commit comments

Comments
 (0)