use async_trait::async_trait;
use serde::{Deserialize, Serialize};
#[derive(Debug, thiserror::Error)]
pub enum OptimizerError {
#[error("Sampling error: {0}")]
Sampling(String),
#[error("Evaluation error: {0}")]
Evaluation(String),
#[error("LLM error: {0}")]
Llm(String),
#[error("Optimization error: {0}")]
Optimization(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OptimizerResult {
pub best_instruction: String,
pub best_score: f64,
pub iterations: usize,
pub score_history: Vec<(usize, f64)>,
}
#[async_trait]
pub trait AgentOptimizer: Send + Sync {
async fn optimize(
&self,
initial_instruction: &str,
model_id: &str,
) -> Result<OptimizerResult, OptimizerError>;
}
#[cfg(test)]
mod tests {
use super::*;
fn _assert_object_safe(_: &dyn AgentOptimizer) {}
#[test]
fn optimizer_result_serde() {
let result = OptimizerResult {
best_instruction: "Be helpful".into(),
best_score: 0.9,
iterations: 5,
score_history: vec![(0, 0.5), (1, 0.7), (2, 0.9)],
};
let json = serde_json::to_string(&result).unwrap();
let deserialized: OptimizerResult = serde_json::from_str(&json).unwrap();
assert!((deserialized.best_score - 0.9).abs() < f64::EPSILON);
}
}