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(
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}