use std::collections::HashMap;
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use crate::config::ModelOverride;
use crate::config::config_base_dir;
use crate::config::store::{load_all_from_dir, move_to_unused, save_yaml};
pub fn models_config_dir() -> PathBuf {
config_base_dir().join("llm-manager").join("models")
}
pub fn unused_config_dir() -> PathBuf {
config_base_dir().join("llm-manager").join("unused")
}
pub fn key_from_display(display_name: &str) -> String {
display_name.replace(std::path::MAIN_SEPARATOR, "__")
}
pub fn display_from_key(key: &str) -> String {
key.replace("__", std::path::MAIN_SEPARATOR_STR)
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelConfigStore {
models_dir: PathBuf,
unused_dir: PathBuf,
model_dirs: Vec<PathBuf>,
cache: HashMap<String, ModelOverride>,
}
impl ModelConfigStore {
pub fn new(model_dirs: Vec<PathBuf>) -> Self {
let models_dir = models_config_dir();
let unused_dir = unused_config_dir();
let cache = load_all_from_dir(&models_dir);
Self {
models_dir,
unused_dir,
model_dirs,
cache,
}
}
pub fn get(&self, display_name: &str) -> Option<&ModelOverride> {
let key = key_from_display(display_name);
self.cache.get(&key)
}
pub fn save(&mut self, display_name: &str, config: &ModelOverride) {
let key = key_from_display(display_name);
save_yaml(&key, config, &self.models_dir, &self.unused_dir);
self.cache.insert(key, config.clone());
}
pub fn delete(&mut self, display_name: &str) {
let key = key_from_display(display_name);
move_to_unused(&key, &self.models_dir, &self.unused_dir);
self.cache.remove(&key);
}
pub fn keys(&self) -> Vec<String> {
let mut keys: Vec<String> = self
.cache
.keys()
.map(|k| display_from_key(k))
.collect();
keys.sort();
keys
}
}
impl Default for ModelConfigStore {
fn default() -> Self {
Self::new(vec![])
}
}