meshscale-worker-template / GUI_API_AUDIT.md
tostido's picture
Build MeshScale CPU worker template
96ef23c verified
|
Raw
History Blame Contribute Delete
35.8 kB

KEY System GUI API Audit

Generated: January 3, 2026
Purpose: Specification for GUI redesign - All public APIs, data structures, actions, and observable state


Table of Contents

  1. Public APIs
  2. Data Structures
  3. User Actions
  4. Observable State
  5. Event System
  6. Configuration Schema

1. Public APIs

1.1 Brain Module (brain.py)

Brain (Abstract Base Class)

class Brain(ABC):
    # Properties
    @property id: str                    # Unique brain identifier (12 char hex)
    @property generation: int            # Generation number
    @property fitness: Optional[float]   # Fitness score (settable)
    @property param_count: int           # Total trainable parameters
    @property brain_type: str            # Architecture type ('mlp', 'lora', 'random')
    
    # Core Methods (abstract)
    def forward(inputs: Dict[str, Any]) -> Dict[str, Any]
    def get_params() -> np.ndarray       # Flatten all params to 1D
    def set_params(params: np.ndarray)   # Load params from 1D array
    
    # State Management (for stateful brains)
    def get_state() -> Dict[str, Any]
    def set_state(state: Dict[str, Any])
    def reset_state()
    
    # Evolution Interface
    def mutate(rate: float = None, scale: float = None) -> Brain
    def crossover(other: Brain, method: str = 'uniform') -> Brain
    def copy() -> Brain
    
    # Serialization
    def save(path: Path)
    @classmethod load(path: Path) -> Brain
    def to_dict() -> Dict[str, Any]

MLPBrain (Concrete)

class MLPBrain(Brain):
    # Properties
    input_size: int
    hidden_size: int
    output_size: int
    activation: Callable  # 'tanh', 'relu', 'sigmoid', 'linear'
    
    # Weights (internal)
    w1: np.ndarray  # (input_size, hidden_size)
    b1: np.ndarray  # (hidden_size,)
    w2: np.ndarray  # (hidden_size, output_size)
    b2: np.ndarray  # (output_size,)

LoRABrain (VLM Adapter Evolution)

class LoRABrain(Brain):
    # Configuration
    lora_rank: int = 8
    lora_alpha: int = 16
    target_modules: List[str] = ['q_proj', 'v_proj']
    hidden_dim: int = 2048
    test_mode: bool = False
    
    # Class-level (shared singleton)
    _base_model: Model           # Frozen VLM (shared)
    _processor: Processor        # Tokenizer/processor (shared)
    
    # Instance-level
    _adapter_weights: Dict[str, np.ndarray]  # Per-module LoRA A/B matrices
    _peft_model: PeftModel       # PEFT model instance
    
    # Methods
    def forward(inputs: Dict) -> Dict[str, Any]
        # inputs: {'text': str, 'image': optional, 'video': optional, 'max_new_tokens': int}
        # returns: {'response': str, 'confidence': float}
    
    async def aforward(prompt: str, images=None, max_new_tokens: int = 512) -> str
    
    def get_adapter_weights() -> Dict[str, np.ndarray]
    def apply_to_model()          # Apply evolved weights to PEFT model
    def save_adapter(path: Path)
    @classmethod load_adapter(path: Path) -> LoRABrain
    
    # Quine (Self-Replication)
    def to_source(path: Path = None) -> str    # Generate Python source file
    @classmethod from_source(path: Path) -> LoRABrain
    def replicate(mutation_rate: float = 0.1, mutation_scale: float = 0.1, 
                  output_dir: Path = None) -> Path  # Write mutated child as .py file
    
    async def live(pulse=None, vp=None, perceive_fn=None, max_ticks: int = None)

Factory Functions

def create_Brain(brain_type: str, **kwargs) -> Brain
def create_population(n: int, brain_type: str = 'mlp', **kwargs) -> List[Brain]

1.2 Mobile Population (mobile.py)

class MobilePopulation:
    """Async population where each brain runs its own lifecycle loop"""
    
    # Constructor
    def __init__(
        pulse: Pulse = None,
        vp: ViolationPressure = None,
        children_dir: Path = None,
        max_population: int = 100,
        enable_logging: bool = False,
    )
    
    # Properties (Observable State)
    members: Dict[str, BrainState]  # Active brains
    total_spawned: int
    total_despawned: int
    generation: int
    pulse: Pulse
    vp: ViolationPressure
    
    # Core Methods
    async def spawn(brain: LoRABrain) -> str        # Add brain, returns ID
    async def despawn(brain_id: str)                # Remove brain
    async def run_forever(tick_interval: float = 0.01)
    async def run_for(duration: float = None, ticks: int = None)
    async def shutdown()
    
    # Status
    def status() -> Dict[str, Any]
        # Returns: {
        #   'population_size': int,
        #   'max_population': int,
        #   'total_spawned': int,
        #   'total_despawned': int,
        #   'generation': int,
        #   'running': bool,
        #   'brains': Dict[id, BrainState]
        # }

@dataclass
class BrainState:
    brain: LoRABrain
    task: asyncio.Task
    spawned_at: float
    tick_count: int
    last_fitness: float
    children_spawned: int
    status: str  # 'running', 'stopping', 'cancelled', 'error: ...'

# Convenience Function
async def run_mobile_evolution(
    initial_population: int = 5,
    duration: float = None,
    ticks: int = 100,
    layers: List[int] = None,
) -> MobilePopulation

1.3 Population Manager (population.py)

class PopulationManager:
    """NEAT-inspired population management with speciation"""
    
    # Constructor
    def __init__(
        trait_keys: List[str],
        population_size: int,
        fitness_fn: Callable[[Node], float],
        config: SpeciesConfig = None,
        brain_factory: Optional[Callable] = None,
    )
    
    # Properties (Observable State)
    population: List[Node]
    species_list: List[Species]
    generation: int
    best_node: Node
    best_fitness: float
    history: List[Dict]
    trait_keys: List[str]
    config: SpeciesConfig
    
    # Core Methods
    def evaluate(verbose: bool = False) -> List[float]
    def speciate(verbose: bool = False)
    def reproduce() -> Dict  # Returns: {'mutations': int, 'crossovers': int, 'elites': int, 'eliminated': int}
    def step(verbose: bool = False) -> Dict  # evaluate + speciate + reproduce
    
    # Query Methods
    def get_snapshot() -> Dict[str, Any]  # Comprehensive population state
    def get_best() -> Tuple[Node, float]
    def get_species_info() -> List[Dict]
    
    # Serialization
    def to_checkpoint_dict() -> Dict
    @staticmethod from_checkpoint_dict(data: Dict, fitness_fn: Callable, brain_factory=None) -> PopulationManager

@dataclass
class SpeciesConfig:
    genetic_distance_threshold: float = 0.35
    max_stagnation: int = 50
    elitism: int = 0
    survival_threshold: float = 0.2
    crossover_rate: float = 0.7
    min_species_size: int = 3
    tournament_size: int = 3

class Species:
    id: int
    representative: Node
    members: List[Node]
    generation_created: int
    last_improvement: int
    best_fitness: float
    avg_fitness: float
    
    def get_avg_fitness() -> float
    def get_best_fitness() -> float
    def is_stagnant(current_gen: int, max_stagnation: int) -> bool
    def contains_node(node, threshold: float) -> bool
    def update_representative()

def genetic_distance(node1, node2) -> float  # Returns 0-1+

1.4 VLM Base (vlm_base.py)

# Configuration
@dataclass
class VLMConfig:
    model_name: str = "Qwen/Qwen2.5-VL-3B-Instruct"
    quantization: Literal['none', '8bit', '4bit'] = '4bit'
    device: str = 'auto'
    torch_dtype: str = 'float16'
    trust_remote_code: bool = True
    use_flash_attention: bool = False
    max_memory: Optional[Dict[str, str]] = None
    offload_folder: Optional[str] = None
    min_pixels: int = 256 * 28 * 28
    max_pixels: int = 1280 * 28 * 28

# Singleton API
def configure(
    model_name: str = None,
    quantization: Literal['none', '8bit', '4bit'] = None,
    device: str = None,
    torch_dtype: str = None,
    use_flash_attention: bool = None,
    max_memory: Dict[str, str] = None,
    offload_folder: str = None,
    min_pixels: int = None,
    max_pixels: int = None,
) -> VLMConfig

def get_config() -> VLMConfig
def get_base_model() -> Model      # Singleton, loads on first call
def get_processor() -> Processor   # Singleton
def reload()                       # Force reload with current config

1.5 Configuration (config.py)

def load_config(path: Path = None) -> Dict[str, Any]
def get(section: str, key: str = None, default: Any = None) -> Any
def reload() -> Dict[str, Any]
def get_defaults() -> Dict[str, Any]

1.6 Causation Explorer (explorer.py)

@dataclass
class Event:
    timestamp: float
    component: str
    event_type: str  # 'state_change', 'threshold_crossed', 'transition'
    data: Dict[str, Any]
    event_id: str
    
    def to_dict() -> Dict[str, Any]

@dataclass
class CausationLink:
    from_event: str
    to_event: str
    causation_type: str  # 'temporal', 'correlation', 'threshold', 'direct'
    strength: float      # 0.0-1.0
    explanation: str
    metrics: List[str]

class CausationExplorer:
    # Properties
    graph: nx.DiGraph           # Causation graph (NetworkX)
    events: Dict[str, Event]
    events_by_component: Dict[str, List[str]]
    events_by_type: Dict[str, List[str]]
    metric_history: Dict[str, deque]
    thresholds: Dict[str, Dict]  # Configurable thresholds
    
    # Event Management
    def add_event(event: Event) -> List[CausationLink]
    
    # Exploration
    def explore_backwards(event_id: str, max_depth: int = 10) -> List[Dict]
    def explore_forwards(event_id: str, max_depth: int = 10) -> List[Dict]
    def find_path(from_id: str, to_id: str) -> Optional[List[Dict]]
    def get_event_summary(event_id: str) -> Dict[str, Any]
    
    # Search
    def search(query: str) -> List[Dict]
    def search_by_metric(metric: str, min_val: float = None, max_val: float = None) -> List[Dict]
    
    # Statistics
    def stats() -> Dict[str, Any]
    
    # Data Loading
    def load_from_json(filepath: Path) -> int
    def load_from_jsonl(filepath: Path) -> int
    def load_all_jsonl(log_dir: Path = None) -> int
    def load_from_shared_state(filepath: Path = None) -> int
    def load_from_logs(log_dir: Path = None) -> int
    def load_all(data_dir: Path = None) -> Dict[str, int]
    
    # Export
    def save_to_json(filepath: Path)
    def to_numpy() -> Tuple[np.ndarray, np.ndarray, List[str]]  # features, adjacency, event_ids
    def to_dataframe() -> pd.DataFrame

1.7 Fitness Functions (fitness.py, fitness_code.py)

Base Classes

class Fitness(ABC):
    @abstractmethod def evaluate(node: Any, context: Dict = None) -> float
    def evaluate_batch(nodes: List, context: Dict = None) -> np.ndarray
    @property name: str
    @property is_minimization: bool

class FunctionFitness(Fitness):  # Wrap lambda as Fitness
class CompositeFitness(Fitness): # Weighted combination

Benchmark Functions

class SphereFitness(Fitness)      # f(x) = -sum(x_i^2)
class RastriginFitness(Fitness)   # Multimodal, many local optima
class RosenbrockFitness(Fitness)  # Narrow curved valley

VLM Fitness

@dataclass
class VLMTask:
    prompt: str
    image: Optional[Union[str, Path, np.ndarray]] = None
    video: Optional[Union[str, Path]] = None
    expected: Optional[str] = None
    keywords: List[str] = []
    forbidden: List[str] = []
    bbox_expected: Optional[List[float]] = None
    max_tokens: int = 128
    weight: float = 1.0

class VLMFitness(Fitness):
    def __init__(tasks: List[VLMTask], time_penalty: float = 0.0, ...)
    def evaluate(node, context=None) -> float

Code Understanding Fitness

@dataclass
class CodeTask:
    file_path: str
    code_snippet: str
    question: str
    expected_keywords: List[str]
    task_type: str  # 'comprehension', 'pattern', 'reasoning'
    difficulty: float = 1.0

class CodeFitness:
    def __init__(config: CodeFitnessConfig = None)
    def evaluate(adapter_id: str) -> float
    def evaluate_single(adapter, prompt: str, code_snippet: str, expected_keywords: List[str]) -> float

1.8 Pulse & Pressure (pulse.py, pressure.py)

Pulse (System Clock)

class Pulse:
    # Properties
    rate: float      # Breaths per second
    phase: float     # 0 to 2π
    depth: float     # 0 to 1
    cycle: int       # Completed cycles
    intensity: float # Multiplier
    
    # Methods
    def tick() -> Dict[str, float]  # Advance pulse, return state
    def state() -> Dict[str, float] # {'depth', 'phase', 'cycle', 'intensity', 'timestamp'}
    def value() -> float            # depth * intensity
    def is_inhale() -> bool         # phase < π
    def is_exhale() -> bool         # phase >= π
    def set_rate(rate: float)
    def set_intensity(intensity: float)

Violation Pressure (Loss Function)

class ViolationClass(Enum):
    VP0 = "VP0"  # 0.00-0.25: Stable
    VP1 = "VP1"  # 0.25-0.50: Drifting
    VP2 = "VP2"  # 0.50-0.75: Unstable
    VP3 = "VP3"  # 0.75-0.99: Critical
    VP4 = "VP4"  # >= 1.00: Collapse

@dataclass
class StabilityEnvelope:
    center: float = 0.5
    radius: float = 0.25
    compression: float = 1.0

class ViolationPressure:
    envelopes: Dict[str, StabilityEnvelope]
    
    def set_envelope(trait: str, center: float, radius: float, compression: float)
    def get_envelope(trait: str) -> StabilityEnvelope
    def compute(traits: Dict[str, float]) -> Tuple[float, Dict[str, float]]  # (total_vp, breakdown)
    def classify(total_vp: float) -> ViolationClass
    def error(traits: Dict[str, float]) -> float  # Simple loss value
    
    # ML Integration
    def as_loss_fn() -> Callable
    def torch_loss(values, centers, radii) -> Tensor

1.9 Tracking (tracking.py)

WandB Tracker

class WandbTracker:
    def __init__(project: str = "evolutionary-nlp", entity: str = None, enabled: bool = True)
    def start_run(name: str = None, config: Dict = None, tags: List[str] = None)
    def log_generation(generation: int, fitness: np.ndarray, species_info: List[Dict] = None, extra_metrics: Dict = None)
    def log_evaluation(generation: int, train_metrics: Dict, eval_metrics: Dict)
    def log_population_viz(generation: int, embedding: np.ndarray, labels: np.ndarray, fitness: np.ndarray)
    def log_vlm_inference(adapter_id, file, task_type, question, response, prompt_tokens, output_tokens, inference_ms, ...)
    def log_vlm_fitness(adapter_id, fitness, scores, task_types, step=None)
    def log_causation_event(event_type, component, data, links=None, step=None)
    def log_adapter_population(generation, adapter_fitness, adapter_similarity=None, anomaly_ratio=None, diversity_score=None)
    def save_inference_table()
    def finish()

TensorBoard Tracker

class TensorBoardTracker:
    def __init__(log_dir: str = "runs", experiment_name: str = None, enabled: bool = True)
    def log_generation(generation: int, fitness: np.ndarray, species_info: List[Dict] = None, extra_metrics: Dict = None)
    def log_evaluation(generation: int, train_metrics: Dict, eval_metrics: Dict)
    def close()

Unified Tracker

class EvolutionTracker:
    def __init__(backend: str = "auto", project: str = "evolutionary-nlp", log_dir: str = "runs")
        # backend: "wandb", "tensorboard", "auto", "none"
    def start_run(name: str = None, config: Dict = None)
    def log_generation(generation: int, fitness: np.ndarray, species_info: List[Dict] = None, extra_metrics: Dict = None)
    def log_evaluation(generation: int, train_metrics: Dict, eval_metrics: Dict)
    def finish()

1.10 Checkpointing (checkpoints.py)

@dataclass
class CheckpointMetadata:
    name: str
    version: str
    timestamp: str
    generation: int
    best_fitness: float
    avg_fitness: float
    num_species: int
    population_size: int
    config_hash: str
    notes: str = ""

@dataclass
class Checkpoint:
    metadata: CheckpointMetadata
    config: Dict
    population_traits: List[Dict]
    history: List[Dict]
    species_data: Optional[Dict]
    nlp_weights: Optional[bytes]
    event_log: Optional[List[Dict]]
    
    def save(path: Path = None) -> Path
    @classmethod load(path: Path) -> Checkpoint

# Functions
def create_checkpoint(name, generation, config, population, history, ...) -> Checkpoint
def list_checkpoints(name_filter: str = None) -> List[CheckpointMetadata]
def get_latest_checkpoint(name: str = None) -> Optional[Path]
def compare_checkpoints(ckpt1, ckpt2) -> Dict

class AutoCheckpointer:
    def __init__(name, config, checkpoint_every=50, keep_best=5, keep_recent=3)
    def maybe_checkpoint(generation, population, history, ..., force=False) -> Optional[Path]

1.11 Node (node.py)

@dataclass
class Node:
    traits: Dict[str, float]
    generation: int = 0
    parent_ids: List[str] = []
    brain: Optional[Brain] = None
    fitness: Optional[float] = None
    
    @property id: str
    
    # Methods
    def score(vp: ViolationPressure) -> float
    def mutate(rate: float = 0.1, mutate_brain: bool = True) -> Node
    def crossover(other: Node, cross_brain: bool = True) -> Node
    def think(inputs: Dict) -> Dict
    def has_brain() -> bool
    def attach_brain(brain: Brain)
    def detach_brain() -> Optional[Brain]
    def to_vector(keys: List[str] = None) -> np.ndarray
    @classmethod from_vector(vector: np.ndarray, keys: List[str]) -> Node
    def to_dict() -> Dict
    @classmethod from_dict(data: Dict, brain_class=None) -> Node

# Helper Functions
def random_node(keys: List[str], brain_factory=None) -> Node
def create_nodes(n: int, keys: List[str], brain_factory=None) -> List[Node]
def create_population(n: int, keys: List[str], brain_factory=None) -> List[Node]

2. Data Structures

2.1 Brain State

{
    'id': str,                    # 12-char hex identifier
    'brain_type': str,            # 'mlp', 'lora', 'random'
    'generation': int,            # Generation number
    'param_count': int,           # Total parameters
    'fitness': Optional[float],   # Current fitness
    'parent_ids': List[str],      # Parent brain IDs
    
    # LoRA-specific
    'lora_rank': int,
    'lora_alpha': int,
    'target_modules': List[str],
    'hidden_dim': int,
    'adapter_weights': Dict[str, np.ndarray],
}

2.2 Population Snapshot

{
    # Core
    'generation': int,
    'population_size': int,
    
    # Fitness
    'best_fitness': float,
    'avg_fitness': float,
    'min_fitness': float,
    'max_fitness': float,
    'fitness_std': float,
    'fitness_range': float,
    'selection_pressure': float,
    
    # Species
    'num_species': int,
    'species_sizes': List[int],
    'species_avg_fitnesses': List[float],
    'species_best_fitnesses': List[float],
    'largest_species_size': int,
    'smallest_species_size': int,
    'avg_species_age': float,
    'max_stagnation': int,
    
    # Sklearn Clustering Quality
    'silhouette_score': float,        # [-1, 1]
    'davies_bouldin_score': float,    # [0, inf)
    'calinski_harabasz_score': float, # [0, inf)
    
    # Diversity
    'overall_diversity': float,
    'trait_means': Dict[str, float],
    'trait_stds': Dict[str, float],
    
    # Brain/Neural metrics
    'num_brains': int,
    'brain_ratio': float,
    'avg_brain_params': float,
    'avg_brain_weight_mean': float,
    'avg_brain_weight_std': float,
    'avg_brain_weight_norm': float,
    'brain_weight_norm_std': float,
    
    # LoRA Adapter metrics
    'num_lora_brains': int,
    'avg_lora_params': float,
    'avg_lora_rank': float,
    'lora_weight_diversity': float,
    'avg_adapter_similarity': float,
    'min_adapter_similarity': float,
    'max_adapter_similarity': float,
    'num_anomalous_adapters': int,
    'anomaly_ratio': float,
    
    # Reproduction stats (from step())
    'mutations': int,
    'crossovers': int,
    'elites': int,
    'eliminated': int,
    'step_time_ms': float,
}

2.3 Species Info

{
    'id': int,
    'size': int,
    'avg_fitness': float,
    'best_fitness': float,
    'age': int,                  # Generations since created
    'stagnant_gens': int,        # Generations without improvement
}

2.4 Pulse State

{
    'depth': float,       # 0-1, sine wave position
    'phase': float,       # 0 to 2π
    'cycle': int,         # Completed breath cycles
    'intensity': float,   # Multiplier
    'timestamp': float,   # Last tick time
}

2.5 Violation Pressure State

{
    'total_vp': float,           # 0-1+ overall pressure
    'vp_class': ViolationClass,  # VP0-VP4
    'breakdown': Dict[str, float],  # Per-trait VP values
}

2.6 Mobile Population Status

{
    'population_size': int,
    'max_population': int,
    'total_spawned': int,
    'total_despawned': int,
    'generation': int,
    'running': bool,
    'brains': {
        brain_id: {
            'id': str,
            'generation': int,
            'ticks': int,
            'fitness': float,
            'children': int,
            'status': str,  # 'running', 'stopping', 'cancelled', 'error: ...'
        }
    }
}

2.7 Causation Event

{
    'event_id': str,
    'timestamp': float,
    'component': str,
    'event_type': str,
    'data': Dict[str, Any],
}

2.8 Checkpoint

{
    'metadata': {
        'name': str,
        'version': str,
        'timestamp': str,
        'generation': int,
        'best_fitness': float,
        'avg_fitness': float,
        'num_species': int,
        'population_size': int,
        'config_hash': str,
        'notes': str,
    },
    'config': Dict,
    'population': List[NodeDict],
    'species': List[SpeciesDict],
    'history': List[SnapshotDict],
}

3. User Actions

3.1 Initialization

Action API Call Parameters
Create Population Manager PopulationManager(...) trait_keys, population_size, fitness_fn, config, brain_factory
Create Mobile Population MobilePopulation(...) pulse, vp, children_dir, max_population
Configure VLM vlm_base.configure(...) model_name, quantization, device, ...
Load Config config.load_config(path) path

3.2 Evolution Control

Action API Call Parameters
Step (sync) pm.step(verbose) verbose
Evaluate Only pm.evaluate(verbose) verbose
Speciate Only pm.speciate(verbose) verbose
Reproduce pm.reproduce() -
Run Mobile (forever) await pop.run_forever(tick_interval) tick_interval
Run Mobile (limited) await pop.run_for(duration, ticks) duration, ticks
Shutdown await pop.shutdown() -

3.3 Brain Management

Action API Call Parameters
Spawn Brain await pop.spawn(brain) brain
Despawn Brain await pop.despawn(brain_id) brain_id
Mutate Brain brain.mutate(rate, scale) rate, scale
Crossover Brains brain.crossover(other, method) other, method
Copy Brain brain.copy() -
Replicate (Quine) brain.replicate(mutation_rate, output_dir) mutation_rate, output_dir

3.4 Checkpointing

Action API Call Parameters
Save Checkpoint checkpoint.save(path) path
Load Checkpoint Checkpoint.load(path) path
Create Checkpoint create_checkpoint(...) name, generation, config, population, history, ...
List Checkpoints list_checkpoints(name_filter) name_filter
Get Latest get_latest_checkpoint(name) name
Auto-checkpoint checkpointer.maybe_checkpoint(...) generation, population, ...
Compare compare_checkpoints(ckpt1, ckpt2) ckpt1, ckpt2

3.5 Saving/Loading

Action API Call Parameters
Save Brain brain.save(path) path
Load Brain Brain.load(path) path
Save Adapter lora_brain.save_adapter(path) path
Load Adapter LoRABrain.load_adapter(path) path
Export to Source brain.to_source(path) path
Load from Source LoRABrain.from_source(path) path
Save PM State pm.to_checkpoint_dict() -
Load PM State PopulationManager.from_checkpoint_dict(...) data, fitness_fn

3.6 Tracking

Action API Call Parameters
Start Run tracker.start_run(name, config, tags) name, config, tags
Log Generation tracker.log_generation(gen, fitness, species_info, extra) gen, fitness, ...
Log Evaluation tracker.log_evaluation(gen, train_metrics, eval_metrics) gen, metrics, ...
Log VLM Inference wandb_tracker.log_vlm_inference(...) adapter_id, file, task_type, ...
Log Causation wandb_tracker.log_causation_event(...) event_type, component, data, links
Finish tracker.finish() -

3.7 Causation Exploration

Action API Call Parameters
Add Event explorer.add_event(event) event
Explore Why explorer.explore_backwards(event_id, max_depth) event_id, max_depth
Explore Effects explorer.explore_forwards(event_id, max_depth) event_id, max_depth
Find Path explorer.find_path(from_id, to_id) from_id, to_id
Search Events explorer.search(query) query
Get Stats explorer.stats() -
Load Data explorer.load_all(data_dir) data_dir

3.8 Configuration

Action API Call Parameters
Get Config Value config.get(section, key, default) section, key, default
Reload Config config.reload() -
Set VP Envelope vp.set_envelope(trait, center, radius, compression) trait, center, radius, compression
Set Pulse Rate pulse.set_rate(rate) rate
Set Pulse Intensity pulse.set_intensity(intensity) intensity

4. Observable State

4.1 Real-time Metrics (per step/tick)

Metric Source Update Frequency
Current Generation pm.generation, pop.generation Per step/tick
Population Size len(pm.population), len(pop.members) Per step
Best Fitness pm.best_fitness Per step
Avg Fitness snapshot['avg_fitness'] Per step
Fitness Distribution snapshot fitness stats Per step
Species Count len(pm.species_list) Per step
Pulse State pulse.state() Per tick
VP Level vp.compute(traits) Per tick

4.2 Curves (time series)

Metric Source Chart Type
Fitness over generations pm.history Line chart
Species count over time pm.history Line chart
Diversity over time snapshot['overall_diversity'] Line chart
VP levels over time Per-brain VP values Multi-line
Population size over time pm.history Area chart
Selection pressure snapshot['selection_pressure'] Line chart

4.3 Population Composition

Metric Source Visualization
Species distribution pm.get_species_info() Pie/treemap
Fitness per species Species info Box plot
Trait distributions snapshot['trait_means/stds'] Histogram
Brain type breakdown Population analysis Bar chart
LoRA adapter similarity snapshot['avg_adapter_similarity'] Heatmap

4.4 Individual Brain State

Metric Source Update
Brain ID brain.id Static
Generation brain.generation Static
Param Count brain.param_count Static
Fitness brain.fitness Per eval
Parent IDs brain._parent_ids Static
Adapter Weights lora_brain.get_adapter_weights() On demand

4.5 Causation Graph

Metric Source Visualization
Event count explorer.stats()['total_events'] Counter
Link count explorer.stats()['total_links'] Counter
Graph density explorer.stats()['graph_density'] Gauge
Components explorer.events_by_component Legend
Strongest links explorer.stats()['strongest_links'] Table

5. Event System

5.1 Events to Log/Display

Event Trigger Data
Fitness Improvement New best fitness old_best, new_best, node_id, traits
Species Created New species species_id, founding_node_id, founding_traits
Species Extinct Species dies species_id, age, peak_fitness, cause
Mutation Node mutated parent_id, child_id, parent_traits, child_traits
Crossover Crossover occurs parent1_id, parent2_id, child_id, traits
Selection Generation complete selected_ids, eliminated_ids, elite_ids
Brain Spawn Mobile spawn brain_id, generation, parent_id
Brain Despawn Mobile despawn brain_id, reason, tick_count
VP Threshold VP level change vp_class, total_vp, traits
Checkpoint Saved Checkpoint written filepath, generation, best_fitness
Checkpoint Loaded Checkpoint loaded filepath, generation

5.2 Event Types (CausationExplorer)

  • state_change - General metric update
  • threshold_crossed - VP/metric threshold crossed
  • transition - State machine transition

5.3 Causation Types

  • temporal - Time-based correlation
  • correlation - Metrics changed together
  • threshold - Threshold crossing caused event
  • direct - Known direct causation (pulse→network, etc.)

6. Configuration Schema

6.1 Full config.json Schema

{
  "pressure": {
    "default_center": 0.5,
    "default_radius": 0.25,
    "default_compression": 1.0,
    "envelopes": {
      "<trait_name>": {"center": float, "radius": float, "compression": float}
    }
  },
  "vp_thresholds": {
    "VP0": 0.25, "VP1": 0.5, "VP2": 0.75, "VP3": 0.99,
    "modularity_collapse": 0.3, "organism_collapse": 500
  },
  "convergence": {"mutation_rate": 0.1, "noise_std": 0.05},
  "attractor": {"max_iterations": 1000, "tolerance": 1e-6, "learning_rate": 0.01},
  "pulse": {"rate": 1.0, "intensity": 1.0, "decay": 0.99},
  "population": {
    "size": 6, "dimensions": 10,
    "trait_keys": ["x0", "x1", ...],
    "use_brains": true
  },
  "evolution": {
    "generations": 100, "mutation_rate": 0.3, "mutation_strength": 0.2,
    "crossover_rate": 0.7, "fitness_function": "code",
    "target_species": 5, "log_interval": 10, "mode": "hybrid"
  },
  "speciation": {
    "genetic_distance_threshold": 0.25, "max_stagnation": 15,
    "elitism": 2, "survival_threshold": 0.2,
    "crossover_rate": 0.7, "min_species_size": 3
  },
  "dbscan": {"eps": null, "min_samples": 3, "eps_percentile": 0.7, "scale_features": true},
  "fitness": {
    "function": "code", "bounds_low": -5.12, "bounds_high": 5.12,
    "normalize": true, "invert": true
  },
  "communication": {
    "enabled": false, "max_turns": 10, "task_type": "collaboration",
    "role_pair": ["Developer", "Architect"],
    "scoring_weights": {"turn_engagement": 0.3, "task_completion": 0.3, "coherence": 0.4}
  },
  "node": {"mutation_rate": 0.3, "mutation_strength": 0.2},
  "brain": {
    "enabled": false, "hidden_sizes": [16, 16],
    "activation": "tanh", "mutation_rate": 0.1, "mutation_strength": 0.3
  },
  "lora_brain": {
    "enabled": true, "base_model": "D:/models/Qwen2.5-VL-3B-Instruct",
    "quantization": "4bit", "lora_rank": 8, "lora_alpha": 16,
    "lora_dropout": 0.0, "target_modules": ["q_proj", "v_proj"],
    "hidden_dim": 2048, "use_flash_attention": false
  },
  "vlm": {
    "min_pixels": 200704, "max_pixels": 1003520,
    "max_new_tokens": 150, "code_dir": "F:/folder/key", "tasks_per_eval": 3
  },
  "weight_evolution": {
    "algorithm": "CMA_ES", "sigma_init": 0.1, "weight_decay": 0.0, "fitness_shaping": true
  },
  "nlp_training": {
    "enabled": true, "vocab_size": 1500, "embed_dim": 64,
    "hidden_dim": 128, "max_seq_len": 32, "num_lstm_layers": 1,
    "num_classes": 2, "population_size": 16, "sigma_init": 0.3,
    "train_samples": 64, "eval_samples": 32
  },
  "explorer": {
    "log_dir": "data/logs", "shared_state_path": "data/.shared_simulation_state.json",
    "max_events": 10000,
    "causation_thresholds": {"temporal_window": 1.0, "correlation_min": 0.7, "direct_max_delay": 0.1}
  },
  "checkpointing": {
    "enabled": true, "checkpoint_every": 10, "keep_best": 5,
    "keep_recent": 3, "checkpoint_dir": "checkpoints"
  },
  "logging": {
    "wandb_project": "key-evolution", "wandb_entity": null,
    "tensorboard_enabled": true, "tensorboard_logdir": "runs/key",
    "log_interval": 1, "log_level": "INFO"
  },
  "performance": {
    "batch_size": 5, "tick_delay_ms": 20, "parallel_fitness": true, "num_workers": 4
  },
  "hf_sync": {
    "enabled": true, "dataset_name": null, "sync_checkpoints": true,
    "sync_logs": true, "retry_attempts": 3, "timeout_seconds": 30
  },
  "visualization": {
    "umap_enabled": true, "umap_n_neighbors": 15, "umap_min_dist": 0.1,
    "umap_n_jobs": 1, "plot_every": 10, "max_history_points": 500
  },
  "selection": {"method": "tournament", "tournament_size": 3, "truncation_threshold": 0.5},
  "experiment": {"name": "default", "tags": ["evolution", "bbob"], "seed": 42, "deterministic": true}
}

GUI Design Recommendations

Panels/Views

  1. Dashboard - Overview: generation, best fitness, population size, VP status
  2. Population View - Species tree, fitness distribution, individual brains
  3. Evolution Control - Start/stop/step, parameter adjustments
  4. Brain Inspector - Selected brain details, weights visualization, lineage
  5. Causation Explorer - Event graph, search, exploration tools
  6. Metrics Charts - Fitness curves, diversity, species count over time
  7. Checkpoints - List, load, compare, export
  8. Configuration - Edit config.json sections, VP envelopes
  9. Logs - Real-time event stream, wandb/tensorboard links

Real-time Updates

  • WebSocket or polling for get_snapshot(), pulse.state(), pop.status()
  • Event stream from logger for mutations, crossovers, spawns

Key Interactions

  • Click brain → show details, lineage, weights
  • Click species → filter to species members
  • Click event → explore causation backwards/forwards
  • Drag VP envelope centers/radii in visualization
  • Play/pause/step evolution controls