# DNO: Dynamic Neural Organism 🧬

[![PyPI version](https://badge.fury.io/py/dno.svg)](https://badge.fury.io/py/dno)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

**DNO** (Dynamic Neural Organism) is a PyTorch-based framework for creating biological neural networks that **grow**, **think**, and **evolve** at runtime.

Unlike static deep learning models (like Transformers or CNNs), a DNO is an organism that starts small (as a single seed) and physically evolves its architecture based on the problem complexity.

## 🌟 Why DNO?

| | **Static Models** (Standard AI) | **DNO (Dynamic AI)** |
|---|---|---|
| **Architecture** | Fixed before training (e.g. 12 layers) | **Evolves during training** |
| **Adaptability** | None (Retraining required) | **High** (Grows/Shrinks on demand) |
| **Efficiency** | Wastes computing on simple tasks | Uses **only** needed resources |
| **Lifespan** | Train once, use forever | **Continuous Learning** |

## 📦 Installation

```bash
pip install dno
```

## 🚀 Quick Start

### 1. The "Hello World" of Life
Create a brain, give it a DNA configuration, and let it think.

```python
import torch
import torch.nn as nn
from dno.core.organism import OrganismManager, BaseEvolvableModule
from dno.core.network import DynamicNetwork
from dno.config import DnoConfig
from dno.utils.dashboard import print_organism_status

# 1. DNA Configuration
# entropy_threshold: Level of "confusion" needed to trigger growth (0.0 - 1.0)
config = DnoConfig(entropy_threshold=0.6, growth_alpha=0.5)

# 2. Birth
manager = OrganismManager()
network = DynamicNetwork(manager, config)

# 3. Seed Layer (The first neuron block)
seed = BaseEvolvableModule(nn.Linear(10, 5))
seed.dynamic_id = "seed_cortex"
network.add_layer(seed)

# 4. Live (Forward Pass)
input_data = torch.randn(1, 10)
output = network(input_data)

print(f"Output: {output.shape}")
print_organism_status(manager)
```

---

## 🧠 Core Concepts

### 1. Neurogenesis (Growth) 📈
When the model is "confused" (High Entropy in outputs) for a sustained period, it undergoes **mitosis**. It clones its most active layer, adds microscopic noise (mutation) to the clone, and rewires the brain to accommodate the new capacity.

```python
from dno.core.growth import GrowthEngine
import torch.optim as optim

optimizer = optim.SGD(network.parameters(), lr=0.01)
growth_engine = GrowthEngine(network, config)

# ... inside training loop ...
# If model is consistently confused (entropy high):
if growth_engine.check_growth_trigger(entropy_history, current_step):
    print("🧠 Brain is growing...")
    growth_engine.mitosis("seed_cortex", optimizer)
```

### 2. Natural Selection (Pruning) ✂️
The `SurvivalEngine` monitors the **Utility Score** of every layer. If a layer isn't contributing to information processing (low KL-Divergence between input/output), it is marked for death.

```python
from dno.core.survival import SurvivalEngine

survival = SurvivalEngine(manager, config)

# ... periodically ...
survival.apply_selective_decay(optimizer) # Rot unused weights
survival.garbage_collect(network)         # Remove dead layers
```

### 3. Fluid Serialization 💾
Save the entire organism—including its unique topology, weights, and life history—into a single file.

```python
# Save existence
network.save_dno("my_organism.dno")

# Resurrect
new_network = DynamicNetwork.load_dno("my_organism.dno", module_factory=lambda t: nn.Linear(10, 5))
```

---

## 🧪 Advanced Usage: Interactive Growth
The DNO can grow based on **conversation difficulty**. If you feed it simple data, it remains small. If you feed it complex noise (high entropy), it expands.

See `examples/interactive_demo.py` (or check the repo) for a full simulation where the model adapts to user input complexity in real-time.

## 🤝 Contributing
DNO is an open-source experiment in Artificial Life.

- **Found a bug?** Open an issue.
- **Have an idea for a new organ?** Submit a PR.

## 📜 License
MIT License. **Go build something alive.**
