use color_eyre::{ Result, eyre::WrapErr, }; use human_panic::setup_panic; use std::os::unix::fs; use tracing::{ Level, info, }; use tracing_subscriber::FmtSubscriber; mod chat; mod commands; mod qna; mod setup; const DEFAULT_INSTRUCT: &str = "You are a shady, yet helpful IRC bot. You try to give responses that can be sent in a single IRC response according to the specification."; #[tokio::main] async fn main() -> Result<()> { // Some error sprucing. better_panic::install(); setup_panic!(); let subscriber = FmtSubscriber::builder() .with_max_level(Level::TRACE) .finish(); tracing::subscriber::set_global_default(subscriber) .wrap_err("Failed to setup trace logging.")?; info!("Starting"); let settings = setup::init().await.wrap_err("Failed to initialize.")?; let config = settings.config; // chroot if applicable. if let Ok(chroot_path) = config.get_string("chroot-dir") { info!("Attempting to chroot to {}", chroot_path); fs::chroot(&chroot_path) .wrap_err_with(|| format!("Failed setting chroot '{}'", chroot_path))?; std::env::set_current_dir("/").wrap_err("Couldn't change directory after chroot.")?; } // Setup root path for commands. let cmd_root = if let Ok(command_path) = config.get_string("command-path") { Some(commands::Root::new(command_path)) } else { None }; let handle = qna::LLMHandle::new( config.get_string("api-key").wrap_err("API missing.")?, config .get_string("base-url") .wrap_err("base-url missing.")?, cmd_root, config .get_string("model") .wrap_err("model string missing.")?, config .get_string("instruct") .unwrap_or_else(|_| DEFAULT_INSTRUCT.to_string()), ) .wrap_err("Couldn't initialize LLM handle.")?; let mut c = chat::new(&config, &handle).await?; c.run().await.unwrap(); Ok(()) }