96 lines
3.6 KiB
Rust
96 lines
3.6 KiB
Rust
use std::path::PathBuf;
|
|
|
|
use clap::Parser;
|
|
|
|
/// Default system prompt, compiled into the binary as a fallback.
|
|
const DEFAULT_SYSTEM_PROMPT: &str = include_str!("../prompts/normalize.txt");
|
|
|
|
const DEFAULT_MERGE_PROMPT: &str = include_str!("../prompts/merge.txt");
|
|
|
|
#[derive(Parser, Debug)]
|
|
#[command(version, about = "Furumi Agent: music metadata ingest and normalization")]
|
|
pub struct Args {
|
|
/// IP address and port for the admin web UI
|
|
#[arg(long, env = "FURUMI_AGENT_BIND", default_value = "0.0.0.0:8090")]
|
|
pub bind: String,
|
|
|
|
/// Directory to watch for new music files
|
|
#[arg(long, env = "FURUMI_AGENT_INBOX_DIR")]
|
|
pub inbox_dir: PathBuf,
|
|
|
|
/// Directory for permanently stored and organized music files
|
|
#[arg(long, env = "FURUMI_AGENT_STORAGE_DIR")]
|
|
pub storage_dir: PathBuf,
|
|
|
|
/// PostgreSQL connection URL
|
|
#[arg(long, env = "FURUMI_AGENT_DATABASE_URL")]
|
|
pub database_url: String,
|
|
|
|
/// Ollama API base URL
|
|
#[arg(long, env = "FURUMI_AGENT_OLLAMA_URL", default_value = "http://localhost:11434")]
|
|
pub ollama_url: String,
|
|
|
|
/// Ollama model name
|
|
#[arg(long, env = "FURUMI_AGENT_OLLAMA_MODEL", default_value = "qwen3:14b")]
|
|
pub ollama_model: String,
|
|
|
|
/// Authorization header value for Ollama API (e.g. "Bearer <token>" or "Basic <base64>")
|
|
#[arg(long, env = "FURUMI_AGENT_OLLAMA_AUTH")]
|
|
pub ollama_auth: Option<String>,
|
|
|
|
/// Inbox scan interval in seconds
|
|
#[arg(long, env = "FURUMI_AGENT_POLL_INTERVAL_SECS", default_value_t = 30)]
|
|
pub poll_interval_secs: u64,
|
|
|
|
/// Confidence threshold for auto-approval (0.0 - 1.0)
|
|
#[arg(long, env = "FURUMI_AGENT_CONFIDENCE_THRESHOLD", default_value_t = 0.85)]
|
|
pub confidence_threshold: f64,
|
|
|
|
/// Path to a custom system prompt file (overrides the built-in default)
|
|
#[arg(long, env = "FURUMI_AGENT_SYSTEM_PROMPT_FILE")]
|
|
pub system_prompt_file: Option<PathBuf>,
|
|
|
|
/// Path to a custom merge prompt file (overrides the built-in default)
|
|
#[arg(long, env = "FURUMI_AGENT_MERGE_PROMPT_FILE")]
|
|
pub merge_prompt_file: Option<PathBuf>,
|
|
}
|
|
|
|
impl Args {
|
|
pub fn validate(&self) -> Result<(), Box<dyn std::error::Error>> {
|
|
if !self.inbox_dir.exists() || !self.inbox_dir.is_dir() {
|
|
return Err(format!("Inbox directory {:?} does not exist or is not a directory", self.inbox_dir).into());
|
|
}
|
|
if !self.storage_dir.exists() || !self.storage_dir.is_dir() {
|
|
return Err(format!("Storage directory {:?} does not exist or is not a directory", self.storage_dir).into());
|
|
}
|
|
if !(0.0..=1.0).contains(&self.confidence_threshold) {
|
|
return Err("Confidence threshold must be between 0.0 and 1.0".into());
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Load the system prompt from a custom file or use the built-in default.
|
|
pub fn load_system_prompt(&self) -> Result<String, Box<dyn std::error::Error>> {
|
|
match &self.system_prompt_file {
|
|
Some(path) => {
|
|
tracing::info!("Loading system prompt from {:?}", path);
|
|
Ok(std::fs::read_to_string(path)?)
|
|
}
|
|
None => {
|
|
tracing::info!("Using built-in default system prompt");
|
|
Ok(DEFAULT_SYSTEM_PROMPT.to_owned())
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn load_merge_prompt(&self) -> Result<String, Box<dyn std::error::Error>> {
|
|
match &self.merge_prompt_file {
|
|
Some(path) => {
|
|
tracing::info!("Loading merge prompt from {:?}", path);
|
|
Ok(std::fs::read_to_string(path)?)
|
|
}
|
|
None => Ok(DEFAULT_MERGE_PROMPT.to_owned()),
|
|
}
|
|
}
|
|
}
|