Skip to main content

vtcode_core/commands/
stats.rs

1//! Stats command implementation - show session statistics and performance metrics
2
3use crate::config::types::CapabilityLevel;
4use crate::config::types::{AgentConfig, OutputFormat, PerformanceMetrics};
5use crate::core::agent::core::Agent;
6use crate::tools::handlers::SessionSurface;
7use crate::utils::colors::style;
8use anyhow::Result;
9
10/// Handle the stats command - display session statistics and performance metrics
11pub async fn handle_stats_command(
12    agent: &Agent,
13    detailed: bool,
14    format: String,
15) -> Result<PerformanceMetrics> {
16    let output_format = match format.to_lowercase().as_str() {
17        "text" => OutputFormat::Text,
18        "json" => OutputFormat::Json,
19        "html" => OutputFormat::Html,
20        _ => OutputFormat::Text,
21    };
22
23    println!("{}", style("Session Statistics").cyan().bold());
24
25    let metrics = agent.performance_metrics();
26    let tool_names = agent
27        .tool_registry_ref()
28        .public_tool_names(SessionSurface::Interactive, CapabilityLevel::CodeSearch)
29        .await;
30
31    match output_format {
32        OutputFormat::Text => display_text_stats(agent.config(), &metrics, detailed, &tool_names),
33        OutputFormat::Json => display_json_stats(agent.config(), &metrics, &tool_names),
34        OutputFormat::Html => display_html_stats(agent.config(), &metrics, &tool_names),
35    }
36
37    Ok(metrics)
38}
39
40fn display_text_stats(
41    config: &AgentConfig,
42    metrics: &PerformanceMetrics,
43    detailed: bool,
44    tool_names: &[String],
45) {
46    println!("{} Configuration:", style("[CONFIG]").dim());
47    println!("  Model: {}", style(&config.model).cyan());
48    println!("  Workspace: {}", style(config.workspace.display()).cyan());
49    println!(
50        "  Verbose Mode: {}",
51        if config.verbose {
52            "Enabled"
53        } else {
54            "Disabled"
55        }
56    );
57
58    println!("\n{} Tool Information:", style("").dim());
59    let tool_count = tool_names.len();
60    println!("  Available Tools: {}", style(tool_count).cyan());
61
62    if detailed {
63        println!("  Tools:");
64        for tool_name in tool_names {
65            println!("    • {}", style(tool_name).cyan());
66        }
67    }
68
69    println!("\n{} Performance Metrics:", style("[METRICS]").dim());
70    println!(
71        "  Session Duration: {} seconds",
72        style(metrics.session_duration_seconds).cyan()
73    );
74    println!("  API Calls: {}", style(metrics.total_api_calls).cyan());
75    println!(
76        "  Tool Executions: {}",
77        style(metrics.tool_execution_count).cyan()
78    );
79    println!("  Errors: {}", style(metrics.error_count).red());
80    println!(
81        "  Recovery Rate: {:.1}%",
82        style(metrics.recovery_success_rate * 100.0).green()
83    );
84
85    if let Some(tokens) = metrics.total_tokens_used {
86        println!("  Total Tokens: {}", style(tokens).cyan());
87    }
88
89    println!(
90        "  Avg Response Time: {:.0}ms",
91        style(metrics.average_response_time_ms).cyan()
92    );
93
94    if detailed {
95        println!("\n{} System Information:", style("[SYS]").dim());
96        println!(
97            "  Rust Version: {}",
98            style(env!("CARGO_PKG_RUST_VERSION")).cyan()
99        );
100        println!(
101            "  vtcode Version: {}",
102            style(env!("CARGO_PKG_VERSION")).cyan()
103        );
104        println!(
105            "  Build Profile: {}",
106            if cfg!(debug_assertions) {
107                "Debug"
108            } else {
109                "Release"
110            }
111        );
112    }
113}
114
115fn display_json_stats(config: &AgentConfig, metrics: &PerformanceMetrics, tool_names: &[String]) {
116    let stats = serde_json::json!({
117        "configuration": {
118            "model": config.model,
119            "workspace": config.workspace,
120            "verbose": config.verbose
121        },
122        "tools": {
123            "count": tool_names.len(),
124            "available": tool_names
125        },
126        "performance": {
127            "session_duration_seconds": metrics.session_duration_seconds,
128            "total_api_calls": metrics.total_api_calls,
129            "total_tokens_used": metrics.total_tokens_used,
130            "average_response_time_ms": metrics.average_response_time_ms,
131            "tool_execution_count": metrics.tool_execution_count,
132            "error_count": metrics.error_count,
133            "recovery_success_rate": metrics.recovery_success_rate
134        },
135        "system": {
136            "rust_version": env!("CARGO_PKG_RUST_VERSION"),
137            "vtcode_version": env!("CARGO_PKG_VERSION"),
138            "build_profile": if cfg!(debug_assertions) { "debug" } else { "release" }
139        }
140    });
141
142    let rendered = serde_json::to_string_pretty(&stats)
143        .unwrap_or_else(|error| format!(r#"{{"error":"failed to format stats: {}"}}"#, error));
144    println!("{}", rendered);
145}
146
147fn display_html_stats(config: &AgentConfig, metrics: &PerformanceMetrics, tool_names: &[String]) {
148    println!("<!DOCTYPE html>");
149    println!("<html><head><title>vtcode Statistics</title></head><body>");
150    println!("<h1>vtcode Session Statistics</h1>");
151
152    println!("<h2>Configuration</h2>");
153    println!("<ul>");
154    println!("<li><strong>Model:</strong> {}</li>", config.model);
155    println!(
156        "<li><strong>Workspace:</strong> {}</li>",
157        config.workspace.display()
158    );
159    println!(
160        "<li><strong>Verbose Mode:</strong> {}</li>",
161        if config.verbose {
162            "Enabled"
163        } else {
164            "Disabled"
165        }
166    );
167    println!("</ul>");
168
169    println!("<h2>Tool Information</h2>");
170    println!(
171        "<p><strong>Available Tools:</strong> {}</p>",
172        tool_names.len()
173    );
174    println!("<ul>");
175    for tool_name in tool_names {
176        println!("<li>{}</li>", tool_name);
177    }
178    println!("</ul>");
179
180    println!("<h2>Performance Metrics</h2>");
181    println!("<ul>");
182    println!(
183        "<li><strong>Session Duration:</strong> {} seconds</li>",
184        metrics.session_duration_seconds
185    );
186    println!(
187        "<li><strong>API Calls:</strong> {}</li>",
188        metrics.total_api_calls
189    );
190    println!(
191        "<li><strong>Tool Executions:</strong> {}</li>",
192        metrics.tool_execution_count
193    );
194    println!("<li><strong>Errors:</strong> {}</li>", metrics.error_count);
195    println!(
196        "<li><strong>Recovery Rate:</strong> {:.1}%</li>",
197        metrics.recovery_success_rate * 100.0
198    );
199    if let Some(tokens) = metrics.total_tokens_used {
200        println!("<li><strong>Total Tokens:</strong> {}</li>", tokens);
201    }
202    println!(
203        "<li><strong>Avg Response Time:</strong> {:.0}ms</li>",
204        metrics.average_response_time_ms
205    );
206    println!("</ul>");
207
208    println!("</body></html>");
209}