use do_memory_core::{ComplexityLevel, TaskOutcome};
const _EXECUTION_TIME_MS: &str = "execution_time_ms";
const _SUCCESS_RATE: &str = "success_rate";
const _COMPLEXITY_SCORE: &str = "complexity_score";
const _PATTERN_MATCH_SCORE: &str = "pattern_match_score";
const _MEMORY_USAGE_MB: &str = "memory_usage_mb";
pub struct TimeSeriesExtractor;
impl TimeSeriesExtractor {
pub fn new() -> Self {
Self
}
pub fn extract_metric(
&self,
metric: &str,
episode: &do_memory_core::Episode,
all_episodes: &[do_memory_core::Episode],
) -> Option<f64> {
match metric {
_EXECUTION_TIME_MS => {
let total_time: u64 = episode.steps.iter().map(|step| step.latency_ms).sum();
Some(total_time as f64)
}
_SUCCESS_RATE => {
let success_count = all_episodes
.iter()
.filter(|e| matches!(e.outcome, Some(TaskOutcome::Success { .. })))
.count();
let rate = success_count as f64 / all_episodes.len() as f64;
Some(rate * 100.0) }
_COMPLEXITY_SCORE => {
let score = match episode.context.complexity {
ComplexityLevel::Simple => 1.0,
ComplexityLevel::Moderate => 2.0,
ComplexityLevel::Complex => 3.0,
};
Some(score)
}
_PATTERN_MATCH_SCORE => {
Some(0.8) }
_MEMORY_USAGE_MB => {
Some(50.0) }
_ => None,
}
}
pub fn meets_threshold(&self, values: &[f64], min_points: usize) -> bool {
!values.is_empty() && values.len() >= min_points
}
}
impl Default for TimeSeriesExtractor {
fn default() -> Self {
Self::new()
}
}