collet 0.1.0

Relentless agentic coding orchestrator with zero-drop agent loops
Documentation
//! Evolution configuration — loadable from `[evolution]` section in config.toml.

use serde::{Deserialize, Serialize};

fn default_batch_size() -> usize {
    10
}
fn default_max_cycles() -> u32 {
    20
}
fn default_holdout_ratio() -> f64 {
    0.2
}
fn default_true() -> bool {
    true
}
fn default_evolver_model() -> String {
    "claude-opus-4-6".to_string()
}
fn default_evolver_max_tokens() -> u32 {
    16384
}
fn default_egl_threshold() -> f64 {
    0.05
}
fn default_egl_window() -> usize {
    3
}

/// Configuration for an evolution run.
///
/// Maps to A-Evolve's `EvolveConfig`.  Can be embedded as an `[evolution]`
/// section in Collet's `config.toml` or loaded from a standalone TOML file.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EvolveConfig {
    /// Tasks per solve batch.
    #[serde(default = "default_batch_size")]
    pub batch_size: usize,

    /// Maximum evolution cycles.
    #[serde(default = "default_max_cycles")]
    pub max_cycles: u32,

    /// Fraction of tasks reserved for holdout validation.
    #[serde(default = "default_holdout_ratio")]
    pub holdout_ratio: f64,

    // -- Mutation gating --------------------------------------------------
    /// Allow evolver to mutate system prompts.
    #[serde(default = "default_true")]
    pub evolve_prompts: bool,

    /// Allow evolver to mutate skills.
    #[serde(default = "default_true")]
    pub evolve_skills: bool,

    /// Allow evolver to mutate memory.
    #[serde(default = "default_true")]
    pub evolve_memory: bool,

    /// Allow evolver to mutate tool definitions.
    #[serde(default)]
    pub evolve_tools: bool,

    /// When true, evolver only sees trajectories (no scores/feedback).
    #[serde(default)]
    pub trajectory_only: bool,

    // -- Evolver LLM ------------------------------------------------------
    /// Model used by the evolution engine for analysis and mutation.
    #[serde(default = "default_evolver_model")]
    pub evolver_model: String,

    /// Max tokens for the evolver LLM response.
    #[serde(default = "default_evolver_max_tokens")]
    pub evolver_max_tokens: u32,

    // -- Convergence ------------------------------------------------------
    /// EGL convergence threshold — stop when score improvement < this.
    #[serde(default = "default_egl_threshold")]
    pub egl_threshold: f64,

    /// Number of recent cycles to check for convergence.
    #[serde(default = "default_egl_window")]
    pub egl_window: usize,
}

impl Default for EvolveConfig {
    fn default() -> Self {
        Self {
            batch_size: default_batch_size(),
            max_cycles: default_max_cycles(),
            holdout_ratio: default_holdout_ratio(),
            evolve_prompts: true,
            evolve_skills: true,
            evolve_memory: true,
            evolve_tools: false,
            trajectory_only: false,
            evolver_model: default_evolver_model(),
            evolver_max_tokens: default_evolver_max_tokens(),
            egl_threshold: default_egl_threshold(),
            egl_window: default_egl_window(),
        }
    }
}