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)]
76pub struct TuiConfig {
77 #[serde(default)]
78 pub show_source_labels: bool,
79}
80
81#[derive(Debug, Clone, Default, Deserialize, Serialize)]
83#[serde(rename_all = "lowercase")]
84pub enum AcpTransport {
85 #[default]
87 Stdio,
88 Http,
90 Both,
92}
93
94#[derive(Clone, Deserialize, Serialize)]
95pub struct AcpConfig {
96 #[serde(default)]
97 pub enabled: bool,
98 #[serde(default = "default_acp_agent_name")]
99 pub agent_name: String,
100 #[serde(default = "default_acp_agent_version")]
101 pub agent_version: String,
102 #[serde(default = "default_acp_max_sessions")]
103 pub max_sessions: usize,
104 #[serde(default = "default_acp_session_idle_timeout_secs")]
105 pub session_idle_timeout_secs: u64,
106 #[serde(default = "default_acp_broadcast_capacity")]
107 pub broadcast_capacity: usize,
108 #[serde(skip_serializing_if = "Option::is_none")]
109 pub permission_file: Option<std::path::PathBuf>,
110 #[serde(default)]
113 pub available_models: Vec<String>,
114 #[serde(default = "default_acp_transport")]
116 pub transport: AcpTransport,
117 #[serde(default = "default_acp_http_bind")]
119 pub http_bind: String,
120 #[serde(skip_serializing_if = "Option::is_none")]
125 pub auth_token: Option<String>,
126 #[serde(default = "default_acp_discovery_enabled")]
129 pub discovery_enabled: bool,
130 #[serde(default)]
132 pub lsp: AcpLspConfig,
133}
134
135impl Default for AcpConfig {
136 fn default() -> Self {
137 Self {
138 enabled: false,
139 agent_name: default_acp_agent_name(),
140 agent_version: default_acp_agent_version(),
141 max_sessions: default_acp_max_sessions(),
142 session_idle_timeout_secs: default_acp_session_idle_timeout_secs(),
143 broadcast_capacity: default_acp_broadcast_capacity(),
144 permission_file: None,
145 available_models: Vec::new(),
146 transport: default_acp_transport(),
147 http_bind: default_acp_http_bind(),
148 auth_token: None,
149 discovery_enabled: default_acp_discovery_enabled(),
150 lsp: AcpLspConfig::default(),
151 }
152 }
153}
154
155impl std::fmt::Debug for AcpConfig {
156 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
157 f.debug_struct("AcpConfig")
158 .field("enabled", &self.enabled)
159 .field("agent_name", &self.agent_name)
160 .field("agent_version", &self.agent_version)
161 .field("max_sessions", &self.max_sessions)
162 .field("session_idle_timeout_secs", &self.session_idle_timeout_secs)
163 .field("broadcast_capacity", &self.broadcast_capacity)
164 .field("permission_file", &self.permission_file)
165 .field("available_models", &self.available_models)
166 .field("transport", &self.transport)
167 .field("http_bind", &self.http_bind)
168 .field(
169 "auth_token",
170 &self.auth_token.as_ref().map(|_| "[REDACTED]"),
171 )
172 .field("discovery_enabled", &self.discovery_enabled)
173 .field("lsp", &self.lsp)
174 .finish()
175 }
176}
177
178#[derive(Debug, Clone, Deserialize, Serialize)]
183pub struct AcpLspConfig {
184 #[serde(default = "default_true")]
186 pub enabled: bool,
187 #[serde(default = "default_true")]
189 pub auto_diagnostics_on_save: bool,
190 #[serde(default = "default_acp_lsp_max_diagnostics_per_file")]
192 pub max_diagnostics_per_file: usize,
193 #[serde(default = "default_acp_lsp_max_diagnostic_files")]
195 pub max_diagnostic_files: usize,
196 #[serde(default = "default_acp_lsp_max_references")]
198 pub max_references: usize,
199 #[serde(default = "default_acp_lsp_max_workspace_symbols")]
201 pub max_workspace_symbols: usize,
202 #[serde(default = "default_acp_lsp_request_timeout_secs")]
204 pub request_timeout_secs: u64,
205}
206
207impl Default for AcpLspConfig {
208 fn default() -> Self {
209 Self {
210 enabled: true,
211 auto_diagnostics_on_save: true,
212 max_diagnostics_per_file: default_acp_lsp_max_diagnostics_per_file(),
213 max_diagnostic_files: default_acp_lsp_max_diagnostic_files(),
214 max_references: default_acp_lsp_max_references(),
215 max_workspace_symbols: default_acp_lsp_max_workspace_symbols(),
216 request_timeout_secs: default_acp_lsp_request_timeout_secs(),
217 }
218 }
219}
220
221#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
225#[serde(rename_all = "lowercase")]
226pub enum DiagnosticSeverity {
227 #[default]
228 Error,
229 Warning,
230 Info,
231 Hint,
232}
233
234#[derive(Debug, Clone, Deserialize, Serialize)]
238#[serde(default)]
239pub struct DiagnosticsConfig {
240 pub enabled: bool,
242 #[serde(default = "default_lsp_max_per_file")]
244 pub max_per_file: usize,
245 #[serde(default)]
247 pub min_severity: DiagnosticSeverity,
248}
249impl Default for DiagnosticsConfig {
250 fn default() -> Self {
251 Self {
252 enabled: true,
253 max_per_file: default_lsp_max_per_file(),
254 min_severity: DiagnosticSeverity::default(),
255 }
256 }
257}
258
259#[derive(Debug, Clone, Deserialize, Serialize)]
261#[serde(default)]
262pub struct HoverConfig {
263 pub enabled: bool,
265 #[serde(default = "default_lsp_max_symbols")]
267 pub max_symbols: usize,
268}
269impl Default for HoverConfig {
270 fn default() -> Self {
271 Self {
272 enabled: false,
273 max_symbols: default_lsp_max_symbols(),
274 }
275 }
276}
277
278#[derive(Debug, Clone, Deserialize, Serialize)]
280#[serde(default)]
281pub struct LspConfig {
282 pub enabled: bool,
284 #[serde(default = "default_lsp_mcp_server_id")]
286 pub mcp_server_id: String,
287 #[serde(default = "default_lsp_token_budget")]
289 pub token_budget: usize,
290 #[serde(default = "default_lsp_call_timeout_secs")]
292 pub call_timeout_secs: u64,
293 #[serde(default)]
295 pub diagnostics: DiagnosticsConfig,
296 #[serde(default)]
298 pub hover: HoverConfig,
299}
300impl Default for LspConfig {
301 fn default() -> Self {
302 Self {
303 enabled: false,
304 mcp_server_id: default_lsp_mcp_server_id(),
305 token_budget: default_lsp_token_budget(),
306 call_timeout_secs: default_lsp_call_timeout_secs(),
307 diagnostics: DiagnosticsConfig::default(),
308 hover: HoverConfig::default(),
309 }
310 }
311}