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(agent: &Agent, detailed: bool, format: String) -> Result<PerformanceMetrics> {
12    let output_format = match format.to_lowercase().as_str() {
13        "text" => OutputFormat::Text,
14        "json" => OutputFormat::Json,
15        "html" => OutputFormat::Html,
16        _ => OutputFormat::Text,
17    };
18
19    println!("{}", style("Session Statistics").cyan().bold());
20
21    let metrics = agent.performance_metrics();
22    let tool_names = agent
23        .tool_registry_ref()
24        .public_tool_names(SessionSurface::Interactive, CapabilityLevel::CodeSearch)
25        .await;
26
27    match output_format {
28        OutputFormat::Text => display_text_stats(agent.config(), &metrics, detailed, &tool_names),
29        OutputFormat::Json => display_json_stats(agent.config(), &metrics, &tool_names),
30        OutputFormat::Html => display_html_stats(agent.config(), &metrics, &tool_names),
31    }
32
33    Ok(metrics)
34}
35
36fn display_text_stats(config: &AgentConfig, metrics: &PerformanceMetrics, detailed: bool, tool_names: &[String]) {
37    println!("{} Configuration:", style("[CONFIG]").dim());
38    println!("  Model: {}", style(&config.model).cyan());
39    println!("  Workspace: {}", style(config.workspace.display()).cyan());
40    println!("  Verbose Mode: {}", if config.verbose { "Enabled" } else { "Disabled" });
41
42    println!("\n{} Tool Information:", style("").dim());
43    let tool_count = tool_names.len();
44    println!("  Available Tools: {}", style(tool_count).cyan());
45
46    if detailed {
47        println!("  Tools:");
48        for tool_name in tool_names {
49            println!("    • {}", style(tool_name).cyan());
50        }
51    }
52
53    println!("\n{} Performance Metrics:", style("[METRICS]").dim());
54    println!("  Session Duration: {} seconds", style(metrics.session_duration_seconds).cyan());
55    println!("  API Calls: {}", style(metrics.total_api_calls).cyan());
56    println!("  Tool Executions: {}", style(metrics.tool_execution_count).cyan());
57    println!("  Errors: {}", style(metrics.error_count).red());
58    println!("  Recovery Rate: {:.1}%", style(metrics.recovery_success_rate * 100.0).green());
59
60    if let Some(tokens) = metrics.total_tokens_used {
61        println!("  Total Tokens: {}", style(tokens).cyan());
62    }
63
64    println!("  Avg Response Time: {:.0}ms", style(metrics.average_response_time_ms).cyan());
65
66    if detailed {
67        println!("\n{} System Information:", style("[SYS]").dim());
68        println!("  Rust Version: {}", style(env!("CARGO_PKG_RUST_VERSION")).cyan());
69        println!("  vtcode Version: {}", style(env!("CARGO_PKG_VERSION")).cyan());
70        println!("  Build Profile: {}", if cfg!(debug_assertions) { "Debug" } else { "Release" });
71    }
72}
73
74fn display_json_stats(config: &AgentConfig, metrics: &PerformanceMetrics, tool_names: &[String]) {
75    let stats = serde_json::json!({
76        "configuration": {
77            "model": config.model,
78            "workspace": config.workspace,
79            "verbose": config.verbose
80        },
81        "tools": {
82            "count": tool_names.len(),
83            "available": tool_names
84        },
85        "performance": {
86            "session_duration_seconds": metrics.session_duration_seconds,
87            "total_api_calls": metrics.total_api_calls,
88            "total_tokens_used": metrics.total_tokens_used,
89            "average_response_time_ms": metrics.average_response_time_ms,
90            "tool_execution_count": metrics.tool_execution_count,
91            "error_count": metrics.error_count,
92            "recovery_success_rate": metrics.recovery_success_rate
93        },
94        "system": {
95            "rust_version": env!("CARGO_PKG_RUST_VERSION"),
96            "vtcode_version": env!("CARGO_PKG_VERSION"),
97            "build_profile": if cfg!(debug_assertions) { "debug" } else { "release" }
98        }
99    });
100
101    let rendered = serde_json::to_string_pretty(&stats)
102        .unwrap_or_else(|error| format!(r#"{{"error":"failed to format stats: {error}"}}"#));
103    println!("{rendered}");
104}
105
106fn display_html_stats(config: &AgentConfig, metrics: &PerformanceMetrics, tool_names: &[String]) {
107    println!("<!DOCTYPE html>");
108    println!("<html><head><title>vtcode Statistics</title></head><body>");
109    println!("<h1>vtcode Session Statistics</h1>");
110
111    println!("<h2>Configuration</h2>");
112    println!("<ul>");
113    println!("<li><strong>Model:</strong> {}</li>", config.model);
114    println!("<li><strong>Workspace:</strong> {}</li>", config.workspace.display());
115    println!("<li><strong>Verbose Mode:</strong> {}</li>", if config.verbose { "Enabled" } else { "Disabled" });
116    println!("</ul>");
117
118    println!("<h2>Tool Information</h2>");
119    println!("<p><strong>Available Tools:</strong> {}</p>", tool_names.len());
120    println!("<ul>");
121    for tool_name in tool_names {
122        println!("<li>{tool_name}</li>");
123    }
124    println!("</ul>");
125
126    println!("<h2>Performance Metrics</h2>");
127    println!("<ul>");
128    println!("<li><strong>Session Duration:</strong> {} seconds</li>", metrics.session_duration_seconds);
129    println!("<li><strong>API Calls:</strong> {}</li>", metrics.total_api_calls);
130    println!("<li><strong>Tool Executions:</strong> {}</li>", metrics.tool_execution_count);
131    println!("<li><strong>Errors:</strong> {}</li>", metrics.error_count);
132    println!("<li><strong>Recovery Rate:</strong> {:.1}%</li>", metrics.recovery_success_rate * 100.0);
133    if let Some(tokens) = metrics.total_tokens_used {
134        println!("<li><strong>Total Tokens:</strong> {tokens}</li>");
135    }
136    println!("<li><strong>Avg Response Time:</strong> {:.0}ms</li>", metrics.average_response_time_ms);
137    println!("</ul>");
138
139    println!("</body></html>");
140}