vtcode_core/tools/registry/
telemetry.rs1use std::time::Duration;
8
9#[derive(Debug, Clone, PartialEq, Eq)]
11pub enum ToolTelemetryEvent {
12 ToolExecutionStarted { tool_name: String, has_args: bool },
14
15 ToolExecutionCompleted {
17 tool_name: String,
18 duration: Duration,
19 output_size_bytes: usize,
20 },
21
22 ToolExecutionFailed {
24 tool_name: String,
25 error_type: String,
26 duration: Duration,
27 },
28
29 ToolFallbackDetected {
34 from_tool: String,
36 to_tool: String,
38 reason: String,
40 affected_file: Option<String>,
42 },
43
44 ToolBlocked { tool_name: String, policy_reason: String },
46
47 ToolTimeoutWarning {
49 tool_name: String,
50 elapsed: Duration,
51 ceiling: Duration,
52 percentage: u8,
53 },
54
55 DestructiveOperationWarning {
57 tool_name: String,
58 operation_type: String,
59 affected_files: Vec<String>,
60 has_backup: bool,
61 },
62}
63
64impl ToolTelemetryEvent {
65 pub fn edit_to_patch_fallback(file_path: impl Into<String>, reason: impl Into<String>) -> Self {
67 Self::ToolFallbackDetected {
68 from_tool: "edit_file".to_string(),
69 to_tool: "apply_patch".to_string(),
70 reason: reason.into(),
71 affected_file: Some(file_path.into()),
72 }
73 }
74
75 pub fn delete_and_recreate_warning(tool_name: impl Into<String>, files: Vec<String>, has_backup: bool) -> Self {
77 Self::DestructiveOperationWarning {
78 tool_name: tool_name.into(),
79 operation_type: "delete_and_recreate".to_string(),
80 affected_files: files,
81 has_backup,
82 }
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89
90 #[test]
91 fn test_create_fallback_event() {
92 let event = ToolTelemetryEvent::edit_to_patch_fallback("test.rs", "pattern_not_found");
93
94 match event {
95 ToolTelemetryEvent::ToolFallbackDetected { from_tool, to_tool, reason, affected_file } => {
96 assert_eq!(from_tool, "edit_file");
97 assert_eq!(to_tool, "apply_patch");
98 assert_eq!(reason, "pattern_not_found");
99 assert_eq!(affected_file, Some("test.rs".to_string()));
100 }
101 _ => panic!("Expected ToolFallbackDetected event"),
102 }
103 }
104
105 #[test]
106 fn test_create_destructive_warning() {
107 let event = ToolTelemetryEvent::delete_and_recreate_warning(
108 "apply_patch",
109 vec!["file1.rs".to_string(), "file2.rs".to_string()],
110 false,
111 );
112
113 match event {
114 ToolTelemetryEvent::DestructiveOperationWarning {
115 tool_name,
116 operation_type,
117 affected_files,
118 has_backup,
119 } => {
120 assert_eq!(tool_name, "apply_patch");
121 assert_eq!(operation_type, "delete_and_recreate");
122 assert_eq!(affected_files.len(), 2);
123 assert!(!has_backup);
124 }
125 _ => panic!("Expected DestructiveOperationWarning event"),
126 }
127 }
128}