use serde::Deserialize;
use thiserror::Error;
use crate::domain::service::{
DEFAULT_PLUGIN_DEADLINE, DEFAULT_STREAMING_BUFFER_SIZE, DEFAULT_SUMMARY_BUFFER_SIZE,
};
#[derive(Debug, Clone, Deserialize)]
pub struct ChatEngineConfig {
#[serde(default = "defaults::plugin_deadline_secs")]
pub plugin_deadline_secs: u64,
#[serde(default = "defaults::ndjson_buffer_size")]
pub ndjson_buffer_size: usize,
#[serde(default = "defaults::summary_buffer_size")]
pub summary_buffer_size: usize,
#[serde(default = "defaults::retention_cleanup_interval_hours")]
pub retention_cleanup_interval_hours: u64,
#[serde(default = "defaults::retention_max_sessions_per_tick")]
pub retention_max_sessions_per_tick: u32,
#[serde(default = "defaults::retention_max_deletes_per_session")]
pub retention_max_deletes_per_session: u32,
#[serde(default)]
pub default_share_token_ttl: Option<u64>,
#[serde(default)]
pub webhook_endpoints: Vec<String>,
#[serde(default)]
pub llm_gateway_base_url: Option<String>,
#[serde(default)]
pub share_base_url: Option<String>,
#[serde(default)]
pub enable_search: bool,
}
impl Default for ChatEngineConfig {
fn default() -> Self {
Self {
plugin_deadline_secs: defaults::plugin_deadline_secs(),
ndjson_buffer_size: defaults::ndjson_buffer_size(),
summary_buffer_size: defaults::summary_buffer_size(),
retention_cleanup_interval_hours: defaults::retention_cleanup_interval_hours(),
retention_max_sessions_per_tick: defaults::retention_max_sessions_per_tick(),
retention_max_deletes_per_session: defaults::retention_max_deletes_per_session(),
default_share_token_ttl: None,
webhook_endpoints: Vec::new(),
llm_gateway_base_url: None,
share_base_url: None,
enable_search: false,
}
}
}
impl ChatEngineConfig {
pub fn validate(&self) -> Result<(), ConfigError> {
if self.ndjson_buffer_size == 0 {
return Err(ConfigError::ZeroBufferSize {
field: "ndjson_buffer_size",
});
}
if self.summary_buffer_size == 0 {
return Err(ConfigError::ZeroBufferSize {
field: "summary_buffer_size",
});
}
if self.retention_cleanup_interval_hours == 0 {
return Err(ConfigError::ZeroRetentionInterval);
}
if self.retention_max_sessions_per_tick == 0 {
return Err(ConfigError::ZeroRetentionCap {
field: "retention_max_sessions_per_tick",
});
}
if self.retention_max_deletes_per_session == 0 {
return Err(ConfigError::ZeroRetentionCap {
field: "retention_max_deletes_per_session",
});
}
Ok(())
}
}
#[allow(clippy::enum_variant_names)]
#[derive(Debug, Error)]
pub enum ConfigError {
#[error("chat-engine config: {field} must be > 0")]
ZeroBufferSize { field: &'static str },
#[error("chat-engine config: retention_cleanup_interval_hours must be > 0")]
ZeroRetentionInterval,
#[error("chat-engine config: {field} must be > 0")]
ZeroRetentionCap { field: &'static str },
}
mod defaults {
use super::{
DEFAULT_PLUGIN_DEADLINE, DEFAULT_STREAMING_BUFFER_SIZE, DEFAULT_SUMMARY_BUFFER_SIZE,
};
pub(super) fn plugin_deadline_secs() -> u64 {
DEFAULT_PLUGIN_DEADLINE.as_secs()
}
pub(super) fn ndjson_buffer_size() -> usize {
DEFAULT_STREAMING_BUFFER_SIZE
}
pub(super) fn summary_buffer_size() -> usize {
DEFAULT_SUMMARY_BUFFER_SIZE
}
pub(super) fn retention_cleanup_interval_hours() -> u64 {
24
}
pub(super) fn retention_max_sessions_per_tick() -> u32 {
1000
}
pub(super) fn retention_max_deletes_per_session() -> u32 {
1000
}
}
#[cfg(test)]
#[path = "config_tests.rs"]
mod config_tests;