use config::{Config, ConfigError, Environment, File}; use serde::Deserialize; #[derive(Clone, Deserialize, Debug)] #[serde(rename_all = "lowercase")] pub enum StorageKind { Local, } fn default_storage_kind() -> StorageKind { StorageKind::Local } /// Selects the strategy used for PDF ingestion. #[derive(Clone, Deserialize, Debug)] #[serde(rename_all = "kebab-case")] pub enum PdfIngestMode { /// Only rely on classic text extraction (no LLM fallbacks). Classic, /// Prefer fast text extraction, but fall back to the LLM rendering path when needed. LlmFirst, } fn default_pdf_ingest_mode() -> PdfIngestMode { PdfIngestMode::LlmFirst } #[derive(Clone, Deserialize, Debug)] pub struct AppConfig { pub openai_api_key: String, pub surrealdb_address: String, pub surrealdb_username: String, pub surrealdb_password: String, pub surrealdb_namespace: String, pub surrealdb_database: String, #[serde(default = "default_data_dir")] pub data_dir: String, pub http_port: u16, #[serde(default = "default_base_url")] pub openai_base_url: String, #[serde(default = "default_storage_kind")] pub storage: StorageKind, #[serde(default = "default_pdf_ingest_mode")] pub pdf_ingest_mode: PdfIngestMode, } fn default_data_dir() -> String { "./data".to_string() } fn default_base_url() -> String { "https://api.openai.com/v1".to_string() } pub fn get_config() -> Result { let config = Config::builder() .add_source(File::with_name("config").required(false)) .add_source(Environment::default()) .build()?; config.try_deserialize() }