use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum HardwareProfile {
Minimal,
Standard,
Performance,
}
#[derive(Debug, Clone)]
pub struct ProfileConfig {
pub max_context_fill: f64,
pub compaction_threshold: f64,
pub max_tools: usize,
pub structured_prompts: bool,
pub progressive_tools: bool,
}
impl HardwareProfile {
#[must_use]
pub const fn config(self) -> ProfileConfig {
match self {
Self::Minimal => ProfileConfig {
max_context_fill: 0.70,
compaction_threshold: 0.50,
max_tools: 5,
structured_prompts: true,
progressive_tools: true,
},
Self::Standard => ProfileConfig {
max_context_fill: 0.85,
compaction_threshold: 0.70,
max_tools: 10,
structured_prompts: true,
progressive_tools: true,
},
Self::Performance => ProfileConfig {
max_context_fill: 0.95,
compaction_threshold: 0.85,
max_tools: 20,
structured_prompts: false,
progressive_tools: false,
},
}
}
}
#[must_use]
pub fn detect_profile() -> HardwareProfile {
use sysinfo::System;
let sys = System::new_all();
let total_ram_gb = sys.total_memory() / (1024 * 1024 * 1024);
if total_ram_gb < 4 {
HardwareProfile::Minimal
} else if total_ram_gb <= 16 {
HardwareProfile::Standard
} else {
HardwareProfile::Performance
}
}
#[derive(Debug, Clone)]
pub struct ModelInfo {
pub name: String,
pub context_length: u32,
pub parameter_count: Option<u64>,
}
#[must_use]
pub fn adjust_profile(base: HardwareProfile, model: &ModelInfo) -> HardwareProfile {
const THREE_BILLION: u64 = 3_000_000_000;
const SEVEN_BILLION: u64 = 7_000_000_000;
let Some(params) = model.parameter_count else {
return base;
};
if params > SEVEN_BILLION {
base
} else if params <= THREE_BILLION && base == HardwareProfile::Standard {
HardwareProfile::Performance
} else {
base
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn minimal_profile_config() {
let cfg = HardwareProfile::Minimal.config();
assert!((cfg.max_context_fill - 0.70).abs() < f64::EPSILON);
assert!((cfg.compaction_threshold - 0.50).abs() < f64::EPSILON);
assert_eq!(cfg.max_tools, 5);
assert!(cfg.structured_prompts);
assert!(cfg.progressive_tools);
}
#[test]
fn standard_profile_config() {
let cfg = HardwareProfile::Standard.config();
assert!((cfg.max_context_fill - 0.85).abs() < f64::EPSILON);
assert!((cfg.compaction_threshold - 0.70).abs() < f64::EPSILON);
assert_eq!(cfg.max_tools, 10);
}
#[test]
fn performance_profile_config() {
let cfg = HardwareProfile::Performance.config();
assert!((cfg.max_context_fill - 0.95).abs() < f64::EPSILON);
assert_eq!(cfg.max_tools, 20);
assert!(!cfg.structured_prompts);
assert!(!cfg.progressive_tools);
}
#[test]
fn detect_returns_valid_profile() {
let profile = detect_profile();
let _ = profile.config();
}
#[test]
fn adjust_small_model_on_standard_upgrades() {
let model = ModelInfo {
name: "llama3.2:1b".to_string(),
context_length: 8192,
parameter_count: Some(1_000_000_000),
};
assert_eq!(
adjust_profile(HardwareProfile::Standard, &model),
HardwareProfile::Performance
);
}
#[test]
fn adjust_large_model_never_upgrades() {
let model = ModelInfo {
name: "llama3.1:70b".to_string(),
context_length: 128_000,
parameter_count: Some(70_000_000_000),
};
assert_eq!(
adjust_profile(HardwareProfile::Minimal, &model),
HardwareProfile::Minimal
);
assert_eq!(
adjust_profile(HardwareProfile::Standard, &model),
HardwareProfile::Standard
);
assert_eq!(
adjust_profile(HardwareProfile::Performance, &model),
HardwareProfile::Performance
);
}
#[test]
fn adjust_no_param_count_keeps_base() {
let model = ModelInfo {
name: "custom-model".to_string(),
context_length: 4096,
parameter_count: None,
};
assert_eq!(
adjust_profile(HardwareProfile::Minimal, &model),
HardwareProfile::Minimal
);
}
#[test]
fn adjust_small_model_on_minimal_stays_minimal() {
let model = ModelInfo {
name: "llama3.2:1b".to_string(),
context_length: 8192,
parameter_count: Some(1_000_000_000),
};
assert_eq!(
adjust_profile(HardwareProfile::Minimal, &model),
HardwareProfile::Minimal
);
}
#[test]
fn adjust_mid_model_on_standard_stays() {
let model = ModelInfo {
name: "llama3.2:7b".to_string(),
context_length: 8192,
parameter_count: Some(7_000_000_000),
};
assert_eq!(
adjust_profile(HardwareProfile::Standard, &model),
HardwareProfile::Standard
);
}
}