1use serde::{Deserialize, Serialize};
5
6use crate::defaults::default_true;
7
8fn default_acp_agent_name() -> String {
9 "zeph".to_owned()
10}
11
12fn default_acp_agent_version() -> String {
13 env!("CARGO_PKG_VERSION").to_owned()
14}
15
16fn default_acp_max_sessions() -> usize {
17 4
18}
19
20fn default_acp_session_idle_timeout_secs() -> u64 {
21 1800
22}
23
24fn default_acp_broadcast_capacity() -> usize {
25 256
26}
27
28fn default_acp_transport() -> AcpTransport {
29 AcpTransport::Stdio
30}
31
32fn default_acp_http_bind() -> String {
33 "127.0.0.1:9800".to_owned()
34}
35
36fn default_acp_discovery_enabled() -> bool {
37 true
38}
39
40fn default_acp_lsp_max_diagnostics_per_file() -> usize {
41 20
42}
43
44fn default_acp_lsp_max_diagnostic_files() -> usize {
45 5
46}
47
48fn default_acp_lsp_max_references() -> usize {
49 100
50}
51
52fn default_acp_lsp_max_workspace_symbols() -> usize {
53 50
54}
55
56fn default_acp_lsp_request_timeout_secs() -> u64 {
57 10
58}
59fn default_lsp_mcp_server_id() -> String {
60 "mcpls".into()
61}
62fn default_lsp_token_budget() -> usize {
63 2000
64}
65fn default_lsp_max_per_file() -> usize {
66 20
67}
68fn default_lsp_max_symbols() -> usize {
69 5
70}
71fn default_lsp_call_timeout_secs() -> u64 {
72 5
73}
74
75#[derive(Debug, Clone, Copy, Default, Deserialize, Serialize)]
84pub struct TuiConfig {
85 #[serde(default)]
88 pub show_source_labels: bool,
89}
90
91#[derive(Debug, Clone, Default, Deserialize, Serialize)]
93#[serde(rename_all = "lowercase")]
94pub enum AcpTransport {
95 #[default]
97 Stdio,
98 Http,
100 Both,
102}
103
104#[derive(Clone, Deserialize, Serialize)]
119pub struct AcpConfig {
120 #[serde(default)]
122 pub enabled: bool,
123 #[serde(default = "default_acp_agent_name")]
125 pub agent_name: String,
126 #[serde(default = "default_acp_agent_version")]
128 pub agent_version: String,
129 #[serde(default = "default_acp_max_sessions")]
131 pub max_sessions: usize,
132 #[serde(default = "default_acp_session_idle_timeout_secs")]
134 pub session_idle_timeout_secs: u64,
135 #[serde(default = "default_acp_broadcast_capacity")]
137 pub broadcast_capacity: usize,
138 #[serde(skip_serializing_if = "Option::is_none")]
140 pub permission_file: Option<std::path::PathBuf>,
141 #[serde(default)]
144 pub available_models: Vec<String>,
145 #[serde(default = "default_acp_transport")]
147 pub transport: AcpTransport,
148 #[serde(default = "default_acp_http_bind")]
150 pub http_bind: String,
151 #[serde(skip_serializing_if = "Option::is_none")]
156 pub auth_token: Option<String>,
157 #[serde(default = "default_acp_discovery_enabled")]
160 pub discovery_enabled: bool,
161 #[serde(default)]
163 pub lsp: AcpLspConfig,
164}
165
166impl Default for AcpConfig {
167 fn default() -> Self {
168 Self {
169 enabled: false,
170 agent_name: default_acp_agent_name(),
171 agent_version: default_acp_agent_version(),
172 max_sessions: default_acp_max_sessions(),
173 session_idle_timeout_secs: default_acp_session_idle_timeout_secs(),
174 broadcast_capacity: default_acp_broadcast_capacity(),
175 permission_file: None,
176 available_models: Vec::new(),
177 transport: default_acp_transport(),
178 http_bind: default_acp_http_bind(),
179 auth_token: None,
180 discovery_enabled: default_acp_discovery_enabled(),
181 lsp: AcpLspConfig::default(),
182 }
183 }
184}
185
186impl std::fmt::Debug for AcpConfig {
187 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
188 f.debug_struct("AcpConfig")
189 .field("enabled", &self.enabled)
190 .field("agent_name", &self.agent_name)
191 .field("agent_version", &self.agent_version)
192 .field("max_sessions", &self.max_sessions)
193 .field("session_idle_timeout_secs", &self.session_idle_timeout_secs)
194 .field("broadcast_capacity", &self.broadcast_capacity)
195 .field("permission_file", &self.permission_file)
196 .field("available_models", &self.available_models)
197 .field("transport", &self.transport)
198 .field("http_bind", &self.http_bind)
199 .field(
200 "auth_token",
201 &self.auth_token.as_ref().map(|_| "[REDACTED]"),
202 )
203 .field("discovery_enabled", &self.discovery_enabled)
204 .field("lsp", &self.lsp)
205 .finish()
206 }
207}
208
209#[derive(Debug, Clone, Deserialize, Serialize)]
214pub struct AcpLspConfig {
215 #[serde(default = "default_true")]
217 pub enabled: bool,
218 #[serde(default = "default_true")]
220 pub auto_diagnostics_on_save: bool,
221 #[serde(default = "default_acp_lsp_max_diagnostics_per_file")]
223 pub max_diagnostics_per_file: usize,
224 #[serde(default = "default_acp_lsp_max_diagnostic_files")]
226 pub max_diagnostic_files: usize,
227 #[serde(default = "default_acp_lsp_max_references")]
229 pub max_references: usize,
230 #[serde(default = "default_acp_lsp_max_workspace_symbols")]
232 pub max_workspace_symbols: usize,
233 #[serde(default = "default_acp_lsp_request_timeout_secs")]
235 pub request_timeout_secs: u64,
236}
237
238impl Default for AcpLspConfig {
239 fn default() -> Self {
240 Self {
241 enabled: true,
242 auto_diagnostics_on_save: true,
243 max_diagnostics_per_file: default_acp_lsp_max_diagnostics_per_file(),
244 max_diagnostic_files: default_acp_lsp_max_diagnostic_files(),
245 max_references: default_acp_lsp_max_references(),
246 max_workspace_symbols: default_acp_lsp_max_workspace_symbols(),
247 request_timeout_secs: default_acp_lsp_request_timeout_secs(),
248 }
249 }
250}
251
252#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
256#[serde(rename_all = "lowercase")]
257pub enum DiagnosticSeverity {
258 #[default]
259 Error,
260 Warning,
261 Info,
262 Hint,
263}
264
265#[derive(Debug, Clone, Deserialize, Serialize)]
269#[serde(default)]
270pub struct DiagnosticsConfig {
271 pub enabled: bool,
273 #[serde(default = "default_lsp_max_per_file")]
275 pub max_per_file: usize,
276 #[serde(default)]
278 pub min_severity: DiagnosticSeverity,
279}
280impl Default for DiagnosticsConfig {
281 fn default() -> Self {
282 Self {
283 enabled: true,
284 max_per_file: default_lsp_max_per_file(),
285 min_severity: DiagnosticSeverity::default(),
286 }
287 }
288}
289
290#[derive(Debug, Clone, Deserialize, Serialize)]
292#[serde(default)]
293pub struct HoverConfig {
294 pub enabled: bool,
296 #[serde(default = "default_lsp_max_symbols")]
298 pub max_symbols: usize,
299}
300impl Default for HoverConfig {
301 fn default() -> Self {
302 Self {
303 enabled: false,
304 max_symbols: default_lsp_max_symbols(),
305 }
306 }
307}
308
309#[derive(Debug, Clone, Deserialize, Serialize)]
311#[serde(default)]
312pub struct LspConfig {
313 pub enabled: bool,
315 #[serde(default = "default_lsp_mcp_server_id")]
317 pub mcp_server_id: String,
318 #[serde(default = "default_lsp_token_budget")]
320 pub token_budget: usize,
321 #[serde(default = "default_lsp_call_timeout_secs")]
323 pub call_timeout_secs: u64,
324 #[serde(default)]
326 pub diagnostics: DiagnosticsConfig,
327 #[serde(default)]
329 pub hover: HoverConfig,
330}
331impl Default for LspConfig {
332 fn default() -> Self {
333 Self {
334 enabled: false,
335 mcp_server_id: default_lsp_mcp_server_id(),
336 token_budget: default_lsp_token_budget(),
337 call_timeout_secs: default_lsp_call_timeout_secs(),
338 diagnostics: DiagnosticsConfig::default(),
339 hover: HoverConfig::default(),
340 }
341 }
342}