use serde_json::Value;
use crate::core::PreparedMutation;
use crate::evolver::EvolutionSignal;
#[derive(Clone, Debug, Default)]
pub struct SignalExtractorInput {
pub compiler_output: Option<String>,
pub stack_trace: Option<String>,
pub logs: Option<String>,
pub extra: Value,
}
#[derive(Clone, Debug)]
pub struct SandboxExecutionResult {
pub success: bool,
pub stdout: String,
pub stderr: String,
pub duration_ms: u64,
pub message: String,
}
impl SandboxExecutionResult {
pub fn success(stdout: impl Into<String>, duration_ms: u64) -> Self {
Self {
success: true,
stdout: stdout.into(),
stderr: String::new(),
duration_ms,
message: "Mutation executed successfully".into(),
}
}
pub fn failure(
stderr: impl Into<String>,
message: impl Into<String>,
duration_ms: u64,
) -> Self {
Self {
success: false,
stdout: String::new(),
stderr: stderr.into(),
duration_ms,
message: message.into(),
}
}
pub fn to_json(&self) -> Value {
serde_json::json!({
"success": self.success,
"stdout": self.stdout,
"stderr": self.stderr,
"duration_ms": self.duration_ms,
"message": self.message,
})
}
}
pub trait SignalExtractorPort: Send + Sync {
fn extract(&self, input: &SignalExtractorInput) -> Vec<EvolutionSignal>;
}
pub trait SandboxPort: Send + Sync {
fn execute(&self, mutation: &PreparedMutation) -> SandboxExecutionResult;
}
pub trait GeneStorePersistPort: Send + Sync {
fn persist_gene(
&self,
gene_id: &str,
signals: &[String],
strategy: &[String],
validation: &[String],
) -> bool;
fn mark_reused(&self, gene_id: &str, capsule_ids: &[String]) -> bool;
}
#[derive(Clone, Debug, Default)]
pub struct ValidateInput {
pub proposal_id: String,
pub execution_success: bool,
pub stdout: String,
pub stderr: String,
}
pub trait ValidatePort: Send + Sync {
fn validate(&self, input: &ValidateInput) -> crate::evolver::ValidationResult;
}
#[derive(Clone, Debug, Default)]
pub struct EvaluateInput {
pub proposal_id: String,
pub intent: String,
pub original: String,
pub proposed: String,
pub signals: Vec<String>,
}
pub trait EvaluatePort: Send + Sync {
fn evaluate(&self, input: &EvaluateInput) -> crate::pipeline::EvaluationResult;
}
#[derive(Clone, Debug, Default)]
pub struct EvolutionPipelineRequest {
pub issue_id: String,
pub intent: String,
pub signals: Vec<String>,
pub files: Vec<String>,
pub expected_effect: String,
pub diff_payload: String,
}
pub trait EvolutionPipelinePort: Send + Sync {
fn run_pipeline(&self, request: &EvolutionPipelineRequest) -> crate::pipeline::PipelineResult;
}