use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GraphRagConfig {
pub api_url: String,
pub enabled: bool,
pub timeout_secs: u64,
pub incremental: bool,
pub async_index: bool,
pub path_map: Option<String>,
pub api_key: Option<String>,
}
impl Default for GraphRagConfig {
fn default() -> Self {
Self {
api_url: std::env::var("GRAPHRAG_API_URL")
.unwrap_or_else(|_| "http://localhost:7474".to_string()),
enabled: std::env::var("GRAPHRAG_ENABLED")
.map(|v| v == "1" || v.to_lowercase() == "true")
.unwrap_or(false),
timeout_secs: std::env::var("GRAPHRAG_TIMEOUT")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(30),
incremental: std::env::var("GRAPHRAG_INCREMENTAL")
.map(|v| v != "0" && v.to_lowercase() != "false")
.unwrap_or(true),
async_index: std::env::var("GRAPHRAG_ASYNC")
.map(|v| v == "1" || v.to_lowercase() == "true")
.unwrap_or(true),
path_map: std::env::var("GRAPHRAG_PATH_MAP").ok(),
api_key: std::env::var("GRAPHRAG_API_KEY").ok(),
}
}
}
impl GraphRagConfig {
pub fn translate_path(&self, local_path: &str) -> String {
if let Some(ref mapping) = self.path_map {
if let Some((host_prefix, container_prefix)) = mapping.split_once(':') {
if local_path.starts_with(host_prefix) {
return local_path.replacen(host_prefix, container_prefix, 1);
}
}
}
local_path.to_string()
}
const MAX_CONFIG_SIZE: u64 = 1024 * 1024;
pub fn load_from_file(path: &PathBuf) -> Option<Self> {
if path.exists() {
let meta = std::fs::metadata(path).ok()?;
if meta.len() > Self::MAX_CONFIG_SIZE {
return None;
}
let content = std::fs::read_to_string(path).ok()?;
toml::from_str(&content).ok()
} else {
None
}
}
pub fn load() -> Self {
let config_paths = [
dirs::config_dir().map(|p| p.join("securegit/graphrag.toml")),
Some(PathBuf::from(".securegit/graphrag.toml")),
];
let mut config = Self::default();
for path_opt in config_paths.iter().flatten() {
if let Some(file_config) = Self::load_from_file(path_opt) {
if std::env::var("GRAPHRAG_API_URL").is_err() {
config.api_url = file_config.api_url;
}
if std::env::var("GRAPHRAG_ENABLED").is_err() {
config.enabled = file_config.enabled;
}
if std::env::var("GRAPHRAG_TIMEOUT").is_err() {
config.timeout_secs = file_config.timeout_secs;
}
if std::env::var("GRAPHRAG_INCREMENTAL").is_err() {
config.incremental = file_config.incremental;
}
if std::env::var("GRAPHRAG_ASYNC").is_err() {
config.async_index = file_config.async_index;
}
if std::env::var("GRAPHRAG_PATH_MAP").is_err() {
config.path_map = file_config.path_map;
}
if std::env::var("GRAPHRAG_API_KEY").is_err() {
config.api_key = file_config.api_key;
}
break;
}
}
config
}
}