1use std::path::PathBuf;
9use vtcode_commons::VtCodePaths;
10
11use serde::{Deserialize, Serialize};
12
13#[derive(Debug, Clone, Default, Serialize, Deserialize)]
23pub struct SafetyConfig {
24 #[serde(default)]
27 audit: Option<ToolAuditConfig>,
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct ToolAuditConfig {
33 #[serde(default)]
35 enabled: bool,
36 #[serde(default = "default_audit_path")]
38 path: PathBuf,
39 #[serde(default = "default_max_size_bytes")]
41 max_size_bytes: u64,
42 #[serde(default = "default_max_files")]
45 max_files: usize,
46}
47
48impl Default for ToolAuditConfig {
49 fn default() -> Self {
50 Self {
51 enabled: false,
52 path: default_audit_path(),
53 max_size_bytes: default_max_size_bytes(),
54 max_files: default_max_files(),
55 }
56 }
57}
58
59fn default_audit_path() -> PathBuf {
60 VtCodePaths::resolve()
61 .and_then(|paths| paths.state_path("audit/tools.jsonl"))
62 .unwrap_or_default()
63}
64
65fn default_max_size_bytes() -> u64 {
66 32 * 1024 * 1024
67}
68
69fn default_max_files() -> usize {
70 4
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 #[test]
78 fn defaults_disable_audit() {
79 let cfg = ToolAuditConfig::default();
80 assert!(!cfg.enabled);
81 assert_eq!(cfg.max_files, 4);
82 assert_eq!(cfg.max_size_bytes, 32 * 1024 * 1024);
83 }
84
85 #[test]
86 fn safety_config_defaults_to_no_audit() {
87 let cfg = SafetyConfig::default();
88 assert!(cfg.audit.is_none());
89 }
90
91 #[test]
92 fn parses_minimal_toml() {
93 let parsed: ToolAuditConfig = toml::from_str(
94 r#"
95 enabled = true
96 path = "/tmp/audit.jsonl"
97 "#,
98 )
99 .expect("minimal toml");
100 assert!(parsed.enabled);
101 assert_eq!(parsed.path, PathBuf::from("/tmp/audit.jsonl"));
102 assert_eq!(parsed.max_files, 4);
104 assert_eq!(parsed.max_size_bytes, 32 * 1024 * 1024);
105 }
106}