use serde::{Deserialize, Serialize};
use crate::defaults::default_true;
fn default_acp_agent_name() -> String {
"zeph".to_owned()
}
fn default_acp_agent_version() -> String {
env!("CARGO_PKG_VERSION").to_owned()
}
fn default_acp_max_sessions() -> usize {
4
}
fn default_acp_session_idle_timeout_secs() -> u64 {
1800
}
fn default_acp_broadcast_capacity() -> usize {
256
}
fn default_acp_transport() -> AcpTransport {
AcpTransport::Stdio
}
fn default_acp_http_bind() -> String {
"127.0.0.1:9800".to_owned()
}
fn default_acp_discovery_enabled() -> bool {
true
}
fn default_acp_lsp_max_diagnostics_per_file() -> usize {
20
}
fn default_acp_lsp_max_diagnostic_files() -> usize {
5
}
fn default_acp_lsp_max_references() -> usize {
100
}
fn default_acp_lsp_max_workspace_symbols() -> usize {
50
}
fn default_acp_lsp_request_timeout_secs() -> u64 {
10
}
#[cfg(feature = "lsp-context")]
fn default_lsp_mcp_server_id() -> String {
"mcpls".into()
}
#[cfg(feature = "lsp-context")]
fn default_lsp_token_budget() -> usize {
2000
}
#[cfg(feature = "lsp-context")]
fn default_lsp_max_per_file() -> usize {
20
}
#[cfg(feature = "lsp-context")]
fn default_lsp_max_symbols() -> usize {
10
}
#[cfg(feature = "lsp-context")]
fn default_lsp_call_timeout_secs() -> u64 {
5
}
#[derive(Debug, Clone, Copy, Default, Deserialize, Serialize)]
pub struct TuiConfig {
#[serde(default)]
pub show_source_labels: bool,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum AcpTransport {
#[default]
Stdio,
Http,
Both,
}
#[derive(Clone, Deserialize, Serialize)]
pub struct AcpConfig {
#[serde(default)]
pub enabled: bool,
#[serde(default = "default_acp_agent_name")]
pub agent_name: String,
#[serde(default = "default_acp_agent_version")]
pub agent_version: String,
#[serde(default = "default_acp_max_sessions")]
pub max_sessions: usize,
#[serde(default = "default_acp_session_idle_timeout_secs")]
pub session_idle_timeout_secs: u64,
#[serde(default = "default_acp_broadcast_capacity")]
pub broadcast_capacity: usize,
#[serde(skip_serializing_if = "Option::is_none")]
pub permission_file: Option<std::path::PathBuf>,
#[serde(default)]
pub available_models: Vec<String>,
#[serde(default = "default_acp_transport")]
pub transport: AcpTransport,
#[serde(default = "default_acp_http_bind")]
pub http_bind: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub auth_token: Option<String>,
#[serde(default = "default_acp_discovery_enabled")]
pub discovery_enabled: bool,
#[serde(default)]
pub lsp: AcpLspConfig,
}
impl Default for AcpConfig {
fn default() -> Self {
Self {
enabled: false,
agent_name: default_acp_agent_name(),
agent_version: default_acp_agent_version(),
max_sessions: default_acp_max_sessions(),
session_idle_timeout_secs: default_acp_session_idle_timeout_secs(),
broadcast_capacity: default_acp_broadcast_capacity(),
permission_file: None,
available_models: Vec::new(),
transport: default_acp_transport(),
http_bind: default_acp_http_bind(),
auth_token: None,
discovery_enabled: default_acp_discovery_enabled(),
lsp: AcpLspConfig::default(),
}
}
}
impl std::fmt::Debug for AcpConfig {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AcpConfig")
.field("enabled", &self.enabled)
.field("agent_name", &self.agent_name)
.field("agent_version", &self.agent_version)
.field("max_sessions", &self.max_sessions)
.field("session_idle_timeout_secs", &self.session_idle_timeout_secs)
.field("broadcast_capacity", &self.broadcast_capacity)
.field("permission_file", &self.permission_file)
.field("available_models", &self.available_models)
.field("transport", &self.transport)
.field("http_bind", &self.http_bind)
.field(
"auth_token",
&self.auth_token.as_ref().map(|_| "[REDACTED]"),
)
.field("discovery_enabled", &self.discovery_enabled)
.field("lsp", &self.lsp)
.finish()
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct AcpLspConfig {
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default = "default_true")]
pub auto_diagnostics_on_save: bool,
#[serde(default = "default_acp_lsp_max_diagnostics_per_file")]
pub max_diagnostics_per_file: usize,
#[serde(default = "default_acp_lsp_max_diagnostic_files")]
pub max_diagnostic_files: usize,
#[serde(default = "default_acp_lsp_max_references")]
pub max_references: usize,
#[serde(default = "default_acp_lsp_max_workspace_symbols")]
pub max_workspace_symbols: usize,
#[serde(default = "default_acp_lsp_request_timeout_secs")]
pub request_timeout_secs: u64,
}
impl Default for AcpLspConfig {
fn default() -> Self {
Self {
enabled: true,
auto_diagnostics_on_save: true,
max_diagnostics_per_file: default_acp_lsp_max_diagnostics_per_file(),
max_diagnostic_files: default_acp_lsp_max_diagnostic_files(),
max_references: default_acp_lsp_max_references(),
max_workspace_symbols: default_acp_lsp_max_workspace_symbols(),
request_timeout_secs: default_acp_lsp_request_timeout_secs(),
}
}
}
#[cfg(feature = "lsp-context")]
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum DiagnosticSeverity {
#[default]
Error,
Warning,
Info,
Hint,
}
#[cfg(feature = "lsp-context")]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct DiagnosticsConfig {
pub enabled: bool,
#[serde(default = "default_lsp_max_per_file")]
pub max_per_file: usize,
#[serde(default)]
pub min_severity: DiagnosticSeverity,
}
#[cfg(feature = "lsp-context")]
impl Default for DiagnosticsConfig {
fn default() -> Self {
Self {
enabled: true,
max_per_file: default_lsp_max_per_file(),
min_severity: DiagnosticSeverity::default(),
}
}
}
#[cfg(feature = "lsp-context")]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct HoverConfig {
pub enabled: bool,
#[serde(default = "default_lsp_max_symbols")]
pub max_symbols: usize,
}
#[cfg(feature = "lsp-context")]
impl Default for HoverConfig {
fn default() -> Self {
Self {
enabled: false,
max_symbols: default_lsp_max_symbols(),
}
}
}
#[cfg(feature = "lsp-context")]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct LspConfig {
pub enabled: bool,
#[serde(default = "default_lsp_mcp_server_id")]
pub mcp_server_id: String,
#[serde(default = "default_lsp_token_budget")]
pub token_budget: usize,
#[serde(default = "default_lsp_call_timeout_secs")]
pub call_timeout_secs: u64,
#[serde(default)]
pub diagnostics: DiagnosticsConfig,
#[serde(default)]
pub hover: HoverConfig,
}
#[cfg(feature = "lsp-context")]
impl Default for LspConfig {
fn default() -> Self {
Self {
enabled: false,
mcp_server_id: default_lsp_mcp_server_id(),
token_budget: default_lsp_token_budget(),
call_timeout_secs: default_lsp_call_timeout_secs(),
diagnostics: DiagnosticsConfig::default(),
hover: HoverConfig::default(),
}
}
}