feat: Integrated gman with Loki to create a vault and added flags to configure the Loki vault

This commit is contained in:
2025-10-14 18:00:11 -06:00
parent 316ebd6d25
commit 591f204b67
7 changed files with 2174 additions and 145 deletions
+51 -15
View File
@@ -25,6 +25,7 @@ use crate::mcp::{
McpRegistry, MCP_INVOKE_META_FUNCTION_NAME_PREFIX, MCP_LIST_META_FUNCTION_NAME_PREFIX,
};
use anyhow::{anyhow, bail, Context, Result};
use gman::providers::local::LocalProvider;
use indexmap::IndexMap;
use inquire::{list_option::ListOption, validator::Validation, Confirm, MultiSelect, Select, Text};
use log::LevelFilter;
@@ -120,6 +121,7 @@ pub struct Config {
pub editor: Option<String>,
pub wrap: Option<String>,
pub wrap_code: bool,
pub(crate) password_file: Option<PathBuf>,
pub function_calling: bool,
pub mapping_tools: IndexMap<String, String>,
@@ -160,6 +162,9 @@ pub struct Config {
pub clients: Vec<ClientConfig>,
#[serde(skip)]
pub secrets_provider: Option<LocalProvider>,
#[serde(skip)]
pub macro_flag: bool,
#[serde(skip)]
@@ -202,6 +207,7 @@ impl Default for Config {
editor: None,
wrap: None,
wrap_code: false,
password_file: None,
function_calling: true,
mapping_tools: Default::default(),
@@ -241,6 +247,8 @@ impl Default for Config {
clients: vec![],
secrets_provider: None,
macro_flag: false,
info_flag: false,
agent_variables: None,
@@ -304,6 +312,7 @@ impl Config {
config.working_mode = working_mode;
config.info_flag = info_flag;
config.load_secrets_provider();
let setup = async |config: &mut Self| -> Result<()> {
config.load_envs();
@@ -361,6 +370,16 @@ impl Config {
}
}
pub fn secrets_password_file(&self) -> PathBuf {
match &self.password_file {
Some(path) => match path.exists() {
true => path.clone(),
false => gman::config::Config::local_provider_password_file(),
},
None => gman::config::Config::local_provider_password_file(),
}
}
pub fn roles_dir() -> PathBuf {
match env::var(get_env_name("roles_dir")) {
Ok(value) => PathBuf::from(value),
@@ -1949,19 +1968,19 @@ impl Config {
pub fn editor(&self) -> Result<String> {
EDITOR.get_or_init(move || {
let editor = self.editor.clone()
.or_else(|| env::var("VISUAL").ok().or_else(|| env::var("EDITOR").ok()))
.unwrap_or_else(|| {
if cfg!(windows) {
"notepad".to_string()
} else {
"nano".to_string()
}
});
which::which(&editor).ok().map(|_| editor)
})
.clone()
.ok_or_else(|| anyhow!("Editor not found. Please add the `editor` configuration or set the $EDITOR or $VISUAL environment variable."))
let editor = self.editor.clone()
.or_else(|| env::var("VISUAL").ok().or_else(|| env::var("EDITOR").ok()))
.unwrap_or_else(|| {
if cfg!(windows) {
"notepad".to_string()
} else {
"nano".to_string()
}
});
which::which(&editor).ok().map(|_| editor)
})
.clone()
.ok_or_else(|| anyhow!("Editor not found. Please add the `editor` configuration or set the $EDITOR or $VISUAL environment variable."))
}
pub fn repl_complete(
@@ -2394,8 +2413,8 @@ impl Config {
None => String::new(),
};
let output = format!(
"# CHAT: {summary} [{now}]{scope}\n{raw_input}\n--------\n{tool_calls}{output}\n--------\n\n",
);
"# CHAT: {summary} [{now}]{scope}\n{raw_input}\n--------\n{tool_calls}{output}\n--------\n\n",
);
file.write_all(output.as_bytes())
.with_context(|| "Failed to save message")
}
@@ -2504,6 +2523,23 @@ impl Config {
Ok(config)
}
fn load_secrets_provider(&mut self) {
let secrets_password_file = self.secrets_password_file();
if !secrets_password_file.exists() {
eprintln!(
"Warning: secrets password file '{}' does not exist.",
secrets_password_file.display()
);
return;
}
self.secrets_provider = Some(LocalProvider {
password_file: Some(secrets_password_file),
git_branch: None,
..LocalProvider::default()
});
}
fn load_envs(&mut self) {
if let Ok(v) = env::var(get_env_name("model")) {
self.model_id = v;