1use serde::Deserialize;
4
5#[derive(Debug, Clone)]
7pub struct ScratchpadConfig {
8 pub enabled: bool,
9 pub max_notes_per_run: usize,
10 pub remind_after_readonly_tools: usize,
11 pub remind_enabled: bool,
12 pub inject_summary_max_chars: usize,
13 pub inject_on_report_keywords: Vec<String>,
14 pub retention_days: u32,
15 pub coverage_soft_ratio: f64,
17 pub coverage_hard_ratio: f64,
19 pub coverage_hard_block_enabled: bool,
20 pub coverage_count_deferred_as_accounted: bool,
22 pub require_deferred_meta: bool,
24 pub coverage_reviewed_warn_ratio: f64,
26 pub coverage_reviewed_hard_ratio: f64,
28 pub coverage_reviewed_hard_block_enabled: bool,
29 pub auditor_from_scratchpad: bool,
31 pub auditor_include_medium_min: usize,
33}
34
35impl Default for ScratchpadConfig {
36 fn default() -> Self {
37 Self {
38 enabled: true,
39 max_notes_per_run: 2000,
40 remind_after_readonly_tools: 8,
41 remind_enabled: true,
42 inject_summary_max_chars: 6000,
43 inject_on_report_keywords: vec![
44 "审查报告".into(),
45 "final report".into(),
46 "synthesize".into(),
47 "write the report".into(),
48 "写报告".into(),
49 "全库".into(),
50 "全仓".into(),
51 "代码级审核".into(),
52 "代码级审查".into(),
53 "repo-wide".into(),
54 "code-level audit".into(),
55 "deliverables".into(),
56 "audit report".into(),
57 "输出md".into(),
58 "md格式".into(),
59 "md 报告".into(),
60 "code_review".into(),
61 ],
62 retention_days: 30,
63 coverage_soft_ratio: 0.85,
64 coverage_hard_ratio: 0.60,
65 coverage_hard_block_enabled: true,
66 coverage_count_deferred_as_accounted: true,
67 require_deferred_meta: true,
68 coverage_reviewed_warn_ratio: 0.70,
69 coverage_reviewed_hard_ratio: 0.40,
70 coverage_reviewed_hard_block_enabled: true,
71 auditor_from_scratchpad: true,
72 auditor_include_medium_min: 3,
73 }
74 }
75}
76
77#[derive(Debug, Clone, Deserialize, Default)]
79pub struct ScratchpadConfigToml {
80 #[serde(default)]
81 pub enabled: Option<bool>,
82 #[serde(default)]
83 pub max_notes_per_run: Option<usize>,
84 #[serde(default)]
85 pub remind_after_readonly_tools: Option<usize>,
86 #[serde(default)]
87 pub remind_enabled: Option<bool>,
88 #[serde(default)]
89 pub inject_summary_max_chars: Option<usize>,
90 #[serde(default)]
91 pub inject_on_report_keywords: Option<Vec<String>>,
92 #[serde(default)]
93 pub retention_days: Option<u32>,
94 #[serde(default)]
95 pub coverage_soft_ratio: Option<f64>,
96 #[serde(default)]
97 pub coverage_hard_ratio: Option<f64>,
98 #[serde(default)]
99 pub coverage_hard_block_enabled: Option<bool>,
100 #[serde(default)]
101 pub coverage_count_deferred_as_accounted: Option<bool>,
102 #[serde(default)]
103 pub require_deferred_meta: Option<bool>,
104 #[serde(default)]
105 pub coverage_reviewed_warn_ratio: Option<f64>,
106 #[serde(default)]
107 pub coverage_reviewed_hard_ratio: Option<f64>,
108 #[serde(default)]
109 pub coverage_reviewed_hard_block_enabled: Option<bool>,
110 #[serde(default)]
111 pub auditor_from_scratchpad: Option<bool>,
112 #[serde(default)]
113 pub auditor_include_medium_min: Option<usize>,
114}
115
116impl ScratchpadConfigToml {
117 #[must_use]
118 pub fn into_runtime(self) -> ScratchpadConfig {
119 let defaults = ScratchpadConfig::default();
120 ScratchpadConfig {
121 enabled: self.enabled.unwrap_or(defaults.enabled),
122 max_notes_per_run: self.max_notes_per_run.unwrap_or(defaults.max_notes_per_run),
123 remind_after_readonly_tools: self
124 .remind_after_readonly_tools
125 .unwrap_or(defaults.remind_after_readonly_tools),
126 remind_enabled: self.remind_enabled.unwrap_or(defaults.remind_enabled),
127 inject_summary_max_chars: self
128 .inject_summary_max_chars
129 .unwrap_or(defaults.inject_summary_max_chars),
130 inject_on_report_keywords: self
131 .inject_on_report_keywords
132 .unwrap_or(defaults.inject_on_report_keywords),
133 retention_days: self.retention_days.unwrap_or(defaults.retention_days),
134 coverage_soft_ratio: self
135 .coverage_soft_ratio
136 .unwrap_or(defaults.coverage_soft_ratio),
137 coverage_hard_ratio: self
138 .coverage_hard_ratio
139 .unwrap_or(defaults.coverage_hard_ratio),
140 coverage_hard_block_enabled: self
141 .coverage_hard_block_enabled
142 .unwrap_or(defaults.coverage_hard_block_enabled),
143 coverage_count_deferred_as_accounted: self
144 .coverage_count_deferred_as_accounted
145 .unwrap_or(defaults.coverage_count_deferred_as_accounted),
146 require_deferred_meta: self
147 .require_deferred_meta
148 .unwrap_or(defaults.require_deferred_meta),
149 coverage_reviewed_warn_ratio: self
150 .coverage_reviewed_warn_ratio
151 .unwrap_or(defaults.coverage_reviewed_warn_ratio),
152 coverage_reviewed_hard_ratio: self
153 .coverage_reviewed_hard_ratio
154 .unwrap_or(defaults.coverage_reviewed_hard_ratio),
155 coverage_reviewed_hard_block_enabled: self
156 .coverage_reviewed_hard_block_enabled
157 .unwrap_or(defaults.coverage_reviewed_hard_block_enabled),
158 auditor_from_scratchpad: self
159 .auditor_from_scratchpad
160 .unwrap_or(defaults.auditor_from_scratchpad),
161 auditor_include_medium_min: self
162 .auditor_include_medium_min
163 .unwrap_or(defaults.auditor_include_medium_min),
164 }
165 }
166}