From d1dbc2703162f9f5f8f6c680525cf575692bc7d7 Mon Sep 17 00:00:00 2001 From: Evandro Fonseca Junior Date: Thu, 26 Mar 2026 18:55:18 -0300 Subject: [PATCH] feat: expand cli command surface --- crates/localllm-cli/src/main.rs | 157 +++++++++++++++++++++++++++++++- 1 file changed, 156 insertions(+), 1 deletion(-) diff --git a/crates/localllm-cli/src/main.rs b/crates/localllm-cli/src/main.rs index 93c87ae..79f1185 100644 --- a/crates/localllm-cli/src/main.rs +++ b/crates/localllm-cli/src/main.rs @@ -6,6 +6,13 @@ enum OutputFormat { Json, } +#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)] +enum AuthMode { + Off, + LocalOnly, + Protected, +} + #[derive(Debug, Parser)] #[command(name = "localllm", about = "Manage the local LLM backend")] struct Cli { @@ -15,6 +22,9 @@ struct Cli { #[arg(long, global = true)] api_key: Option, + #[arg(long, global = true, default_value = "./models")] + models_dir: String, + #[arg(long, global = true, value_enum, default_value_t = OutputFormat::Text)] format: OutputFormat, @@ -26,6 +36,11 @@ struct Cli { enum Commands { Status, Models(ModelsCommand), + Auth(AuthCommand), + Config(ConfigCommand), + Bench(BenchCommand), + Logs(LogsArgs), + Doctor, } #[derive(Debug, Args)] @@ -37,14 +52,154 @@ struct ModelsCommand { #[derive(Debug, Subcommand)] enum ModelsSubcommand { List, + Scan, + Load(ModelsLoadArgs), + Unload(ModelsUnloadArgs), + Use(ModelsUseArgs), + Watch, + Download(ModelsDownloadArgs), + Remove(ModelsRemoveArgs), +} + +#[derive(Debug, Args)] +struct ModelsLoadArgs { + model: String, + + #[arg(long)] + alias: Option, +} + +#[derive(Debug, Args)] +struct ModelsUnloadArgs { + model: Option, +} + +#[derive(Debug, Args)] +struct ModelsUseArgs { + model: String, +} + +#[derive(Debug, Args)] +struct ModelsDownloadArgs { + repo: String, +} + +#[derive(Debug, Args)] +struct ModelsRemoveArgs { + model: String, +} + +#[derive(Debug, Args)] +struct AuthCommand { + #[command(subcommand)] + command: AuthSubcommand, +} + +#[derive(Debug, Subcommand)] +enum AuthSubcommand { + Status, + Enable(AuthEnableArgs), + Disable, + SetKey(AuthSetKeyArgs), +} + +#[derive(Debug, Args)] +struct AuthEnableArgs { + #[arg(long, value_enum, default_value_t = AuthMode::Protected)] + mode: AuthMode, + + #[arg(long)] + api_key: Option, +} + +#[derive(Debug, Args)] +struct AuthSetKeyArgs { + api_key: String, +} + +#[derive(Debug, Args)] +struct ConfigCommand { + #[command(subcommand)] + command: ConfigSubcommand, +} + +#[derive(Debug, Subcommand)] +enum ConfigSubcommand { + Get(ConfigGetArgs), + Set(ConfigSetArgs), +} + +#[derive(Debug, Args)] +struct ConfigGetArgs { + key: String, +} + +#[derive(Debug, Args)] +struct ConfigSetArgs { + key: String, + value: String, +} + +#[derive(Debug, Args)] +struct BenchCommand { + #[command(subcommand)] + command: BenchSubcommand, +} + +#[derive(Debug, Subcommand)] +enum BenchSubcommand { + Throughput(BenchThroughputArgs), + Smoke, + Suite, + Compare(BenchCompareArgs), +} + +#[derive(Debug, Args)] +struct BenchThroughputArgs { + #[arg(long, default_value_t = 3)] + samples: u32, + + #[arg(long, default_value_t = 256)] + prompt_tokens: u32, + + #[arg(long, default_value_t = 128)] + completion_tokens: u32, +} + +#[derive(Debug, Args)] +struct BenchCompareArgs { + baseline: String, + candidate: String, +} + +#[derive(Debug, Args)] +struct LogsArgs { + #[arg(long, default_value_t = 200)] + lines: u32, } fn main() -> anyhow::Result<()> { let cli = Cli::parse(); - println!("CLI scaffold ready for {:?} at {}", cli.command, cli.server); + println!( + "CLI scaffold ready for {} at {}", + command_summary(&cli.command), + cli.server + ); Ok(()) } +fn command_summary(command: &Commands) -> &'static str { + match command { + Commands::Status => "status", + Commands::Models(_) => "models", + Commands::Auth(_) => "auth", + Commands::Config(_) => "config", + Commands::Bench(_) => "bench", + Commands::Logs(_) => "logs", + Commands::Doctor => "doctor", + } +} + #[cfg(test)] mod tests { use super::Cli;