vtcode_core/commands/
stats.rs1use 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
10pub 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}