vtcode_core/commands/
memory.rs1use crate::memory::{MemoryMonitor, MemoryPressure, MemoryReport};
4use crate::utils::colors::style;
5use anyhow::Result;
6
7pub async fn handle_memory_command() -> Result<MemoryReport> {
9 let monitor = MemoryMonitor::new();
10
11 let report = monitor
13 .get_report()
14 .map_err(|e| anyhow::anyhow!("Failed to generate memory report: {}", e))?;
15
16 println!("{}", style("Memory Usage Report").cyan().bold());
17 display_memory_report(&report);
18
19 Ok(report)
20}
21
22fn display_memory_report(report: &MemoryReport) {
24 println!("\n{} Current Memory Usage:", style("[MEMORY]").dim());
25 println!(
26 " RSS (Resident Set): {} MB",
27 style(format!("{:.1}", report.current_rss_mb)).cyan()
28 );
29
30 println!("\n{} Thresholds:", style("[LIMITS]").dim());
31 println!(
32 " Soft Limit: {} MB (warning level)",
33 style(format!("{:.1}", report.soft_limit_mb)).cyan()
34 );
35 println!(
36 " Hard Limit: {} MB (critical level)",
37 style(format!("{:.1}", report.hard_limit_mb)).red()
38 );
39
40 println!("\n{} Pressure Status:", style("[PRESSURE]").dim());
41 let pressure_str = format!("{}", report.pressure);
42 let pressure_colored = match report.pressure {
43 MemoryPressure::Normal => style(pressure_str).green(),
44 MemoryPressure::Warning => style(pressure_str).red(),
45 MemoryPressure::Critical => style(pressure_str).red().bold(),
46 };
47 println!(" Level: {}", pressure_colored);
48 println!(" Description: {}", report.pressure.description());
49 println!(
50 " Usage: {:.1}% of hard limit",
51 style(format!("{:.1}", report.usage_percent)).cyan()
52 );
53
54 println!("\n{} Recommendations:", style("[RECOMMENDATIONS]").dim());
55 match report.pressure {
56 MemoryPressure::Normal => {
57 println!(" ✓ Memory usage is healthy");
58 println!(" • Continue normal operation");
59 }
60 MemoryPressure::Warning => {
61 println!(" ⚠ Memory approaching soft limit (400 MB)");
62 println!(" • Cache TTL reduced to 2 minutes");
63 println!(" • Least-used entries being evicted");
64 println!(" • Consider reducing cache sizes if continues");
65 }
66 MemoryPressure::Critical => {
67 println!(" ⛔ CRITICAL: Memory at hard limit (600 MB)");
68 println!(" • Aggressive cache eviction active");
69 println!(" • Cache TTL reduced to 30 seconds");
70 println!(" • Immediate cleanup recommended");
71 println!(" • Risk of OOM if memory increases further");
72 }
73 }
74
75 if !report.recent_checkpoints.is_empty() {
77 println!("\n{} Recent Memory Checkpoints:", style("[HISTORY]").dim());
78 for (i, checkpoint) in report.recent_checkpoints.iter().rev().take(5).enumerate() {
79 println!(
80 " [{}] {} MB - {}",
81 i + 1,
82 style(format!(
83 "{:.1}",
84 checkpoint.rss_bytes as f64 / (1024.0 * 1024.0)
85 ))
86 .cyan(),
87 style(&checkpoint.label).dim()
88 );
89 }
90 if report.recent_checkpoints.len() > 5 {
91 println!(
92 " ... and {} more checkpoint{}",
93 report.recent_checkpoints.len() - 5,
94 if report.recent_checkpoints.len() - 5 == 1 {
95 ""
96 } else {
97 "s"
98 }
99 );
100 }
101 }
102
103 println!("\n{} Tip:", style("[INFO]").dim());
104 println!(" Run 'cargo build --release' for optimized memory usage");
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn test_memory_command_execution() {
113 let _cmd = handle_memory_command();
116 }
117
118 #[test]
119 fn test_pressure_recommendations() {
120 assert!(!MemoryPressure::Normal.description().is_empty());
122 assert!(!MemoryPressure::Warning.description().is_empty());
123 assert!(!MemoryPressure::Critical.description().is_empty());
124 }
125}