# Adaptive Memory Management

Dynamic memory management system that automatically adjusts working memory parameters based on task type and complexity.

## Overview

Adaptive Memory Management analyzes developer tasks and automatically optimizes memory parameters (compression threshold, rolling window size) for maximum efficiency. The system classifies tasks into types (debug, refactor, coding) and estimates their complexity to provide optimal memory configuration.

## Key Features

- **Automatic task classification**: Determines task type (debug, refactor, coding)
- **Complexity estimation**: Analyzes task complexity based on context and description
- **Dynamic tuning**: Automatically selects optimal memory parameters
- **Flexible configuration**: Support for custom settings for different teams/projects
- **Zero overhead**: Works without additional API calls

## Quick Start

### Basic Usage

```python
from neoCoder.sdk.adaptive_memory import AdaptiveMemoryManager

# Create manager
manager = AdaptiveMemoryManager()

# Get optimal configuration for task
config = manager.get_memory_config(
    task="Fix the authentication bug in user login",
    context={'complexity': 'medium'}
)

print(f"Compression threshold: {config.compression_threshold}")
print(f"Rolling window size: {config.rolling_window_size}")
print(f"Max tokens: {config.max_tokens}")
```

### With Custom Configuration

```python
from neoCoder.sdk.adaptive_memory import AdaptiveMemoryManager, AdaptiveMemoryConfig

# Create custom configuration
config = AdaptiveMemoryConfig(
    enabled=True,
    default_compression_threshold=0.85,
    default_rolling_window=12,
    debug_compression_threshold=0.95,
    debug_rolling_window=20,
)

manager = AdaptiveMemoryManager(config)
memory_config = manager.get_memory_config("Debug production issue")
```

## Task Classification

The system automatically classifies tasks into three types:

### Debug Tasks
**Keywords**: debug, fix, bug, error, issue

**Characteristics**:
- High compression threshold (0.9+)
- Large rolling window (15+)
- Require more context for analysis

**Examples**:
- "Fix the null pointer exception in data processor"
- "Debug the memory leak in payment service"
- "Resolve the authentication error"

### Refactor Tasks
**Keywords**: refactor, clean, optimize, improve

**Characteristics**:
- Medium compression threshold (0.7)
- Medium rolling window (8)
- Focus on structural changes

**Examples**:
- "Refactor the API layer to use dependency injection"
- "Clean up the database query code"
- "Optimize the search algorithm"

### Coding Tasks
**Keywords**: implement, create, add, write

**Characteristics**:
- Standard compression threshold (0.8)
- Standard rolling window (10)
- Balance between context and performance

**Examples**:
- "Implement OAuth2 authentication"
- "Create a new dashboard for analytics"
- "Add real-time notifications"

## Complexity Estimation

The system estimates task complexity based on:

1. **Explicit indication in context**:
```python
context = {'complexity': 'complex'}  # simple, medium, complex
```

2. **Task description length**:
- Short tasks (< 5 words): -0.1 to complexity
- Long tasks (> 50 words): +0.15 to complexity

3. **Additional context**:
```python
context = {
    'complexity': 'complex',
    'files_involved': 10,
    'estimated_time': '3 days',
}
```

## Configuration

### AdaptiveMemoryConfig

```python
from neoCoder.sdk.adaptive_memory.config import AdaptiveMemoryConfig

config = AdaptiveMemoryConfig(
    # Basic settings
    enabled=True,                           # Enable adaptive management
    
    # Default settings
    default_compression_threshold=0.8,      # Default compression threshold
    default_rolling_window=10,              # Default window size
    
    # Settings for debug tasks
    debug_compression_threshold=0.9,        # High threshold for debug
    debug_rolling_window=15,                # Large window for debug
    
    # Settings for refactor tasks
    refactor_compression_threshold=0.7,     # Medium threshold for refactor
    refactor_rolling_window=8,              # Medium window for refactor
    
    # Complexity thresholds
    high_complexity_threshold=0.8,          # High complexity threshold
    low_complexity_threshold=0.3,           # Low complexity threshold
    complexity_adjustment=0.05,             # Complexity adjustment
)
```

### WorkingMemoryConfig

Manager output:

```python
from neoCoder.sdk.adaptive_memory.config import WorkingMemoryConfig

config = WorkingMemoryConfig(
    compression_threshold=0.9,    # Compression threshold (0.0-1.0)
    rolling_window_size=15,       # Rolling window size
    max_tokens=4000,              # Maximum tokens
)
```

## Architecture

```
AdaptiveMemoryManager
├── TaskClassifier
│   └── classify(task) -> task_type
├── ComplexityEstimator
│   └── estimate(task, context) -> complexity
└── get_memory_config(task, context) -> WorkingMemoryConfig
```

### Components

#### TaskClassifier
Classifies tasks based on keywords:
- Analyzes task description
- Determines type (debug, refactor, coding)
- Uses priority keyword system

#### ComplexityEstimator
Estimates task complexity:
- Checks explicit indication in context
- Analyzes description length
- Returns estimate from 0.0 to 1.0

#### AdaptiveMemoryManager
Coordinates component work:
- Classifies task
- Estimates complexity
- Selects base parameters
- Adjusts for complexity
- Returns optimal configuration

## Usage Examples

### Developer Workflow

```python
manager = AdaptiveMemoryManager()

# Morning: Bug fixing
debug_config = manager.get_memory_config(
    "Fix the SQL injection vulnerability",
    {'complexity': 'complex'}
)
# -> high threshold, large window

# Day: Feature development
feature_config = manager.get_memory_config(
    "Implement real-time notifications",
    {'complexity': 'medium'}
)
# -> standard threshold, standard window

# Evening: Refactoring
refactor_config = manager.get_memory_config(
    "Clean up the API endpoints",
    {'complexity': 'simple'}
)
# -> lower threshold, smaller window
```

### Integration with Orchestrator

```python
from neoCoder.sdk.adaptive_memory import AdaptiveMemoryManager

class SmartOrchestrator:
    def __init__(self):
        self.memory_manager = AdaptiveMemoryManager()
    
    def execute_task(self, task_description, context=None):
        # Get optimal configuration
        memory_config = self.memory_manager.get_memory_config(
            task_description,
            context or {}
        )
        
        # Use configuration
        self.configure_memory(memory_config)
        
        # Execute task
        return self.run_with_config(task_description)
```

### Team Customization

```python
# Configuration for team with large projects
team_config = AdaptiveMemoryConfig(
    enabled=True,
    default_compression_threshold=0.85,
    default_rolling_window=12,
    debug_compression_threshold=0.95,
    debug_rolling_window=20,
    high_complexity_threshold=0.7,  # More sensitive to complexity
    complexity_adjustment=0.1,       # Larger adjustment
)

manager = AdaptiveMemoryManager(team_config)
```

## Testing

```bash
# Unit tests
pytest tests/unit/test_task_classifier.py -v
pytest tests/unit/test_complexity_estimator.py -v
pytest tests/unit/test_adaptive_memory_manager.py -v

# Integration tests
pytest tests/integration/test_adaptive_memory.py -v

# E2E tests
pytest tests/e2e/test_adaptive_memory_e2e.py -v

# All Adaptive Memory tests
pytest tests/ -k "adaptive_memory or task_classifier or complexity_estimator" -v
```

## Performance Metrics

### Task Classification
- **Accuracy**: >95% for explicit keywords
- **Speed**: <1ms per task
- **Overhead**: Zero (no API calls)

### Complexity Estimation
- **Range**: 0.0 - 1.0
- **Granularity**: 0.05
- **Factors**: Context, description length

### Parameter Adaptation
- **Compression threshold**: 0.5 - 1.0
- **Rolling window**: 5 - 20
- **Adjustment time**: <1ms

## Best Practices

1. **Provide context**: Specify complexity explicitly for best results
```python
context = {
    'complexity': 'complex',
    'files_involved': 10,
    'estimated_time': '2 days',
}
```

2. **Use descriptive tasks**: More detailed description = more accurate classification
```python
# Good
"Fix the null pointer exception in the payment processor when handling refunds"

# Bad
"Fix bug"
```

3. **Customize for team**: Adjust thresholds for project specifics
```python
config = AdaptiveMemoryConfig(
    debug_compression_threshold=0.95,  # Your team prefers more context
)
```

4. **Monitor results**: Track adaptation effectiveness
```python
config = manager.get_memory_config(task, context)
log_config(task_type, complexity, config)
```

5. **Test with real tasks**: Verify on typical tasks for your team
```python
test_tasks = [
    "Fix production bug",
    "Refactor legacy code",
    "Implement new feature",
]
for task in test_tasks:
    config = manager.get_memory_config(task)
    assert_valid_config(config)
```

## Troubleshooting

### Incorrect Classification

**Problem**: Task is classified incorrectly

**Solution**:
- Use more explicit keywords
- Add context with explicit type indication
- Check keyword order (debug > refactor > fix)

### Suboptimal Parameters

**Problem**: Memory parameters don't fit the task

**Solution**:
- Explicitly specify complexity in context
- Adjust thresholds in AdaptiveMemoryConfig
- Use more detailed task description

### Disabling Adaptation

**Problem**: Need to use fixed parameters

**Solution**:
```python
config = AdaptiveMemoryConfig(enabled=False)
manager = AdaptiveMemoryManager(config)
# Always returns standard parameters
```

## Roadmap

- [ ] LLM-based classification for complex cases
- [ ] Learning from team historical data
- [ ] Automatic adjustment based on results
- [ ] Support for additional task types
- [ ] Integration with metrics system

## License

MIT License - see LICENSE file for details.
