## feat(cli): add **list** subcommand to show supported models

- Add 'list' subcommand to display all available models with their
  ModelScope IDs
- Implement run_list() function to print formatted table of models
- Update main() to handle the new List command variant
- Add ValueEnum import for clap functionality

style(models): hide internal model variants from CLI help

- Add hide = true attribute to all WhichModel enum variants to
  prevent showing internal model names in CLI help output
- Keep the functionality intact while cleaning up user interface
This commit is contained in:
XiaoYang
2026-01-22 17:09:03 +08:00
parent f010087e97
commit da6229abee
2 changed files with 55 additions and 17 deletions
+39 -1
View File
@@ -1,7 +1,7 @@
use std::{net::IpAddr, str::FromStr, time::Duration}; use std::{net::IpAddr, str::FromStr, time::Duration};
use aha::{models::WhichModel, utils::get_default_save_dir}; use aha::{models::WhichModel, utils::get_default_save_dir};
use clap::{Args, Parser, Subcommand}; use clap::{Args, Parser, Subcommand, ValueEnum};
use modelscope::ModelScope; use modelscope::ModelScope;
use rocket::{ use rocket::{
Config, Config,
@@ -55,6 +55,8 @@ enum Commands {
Download(DownloadArgs), Download(DownloadArgs),
/// Run model inference directly /// Run model inference directly
Run(RunArgs), Run(RunArgs),
/// List all supported models
List,
} }
/// Common/shared arguments for server operations /// Common/shared arguments for server operations
@@ -194,6 +196,41 @@ fn get_model_id(model: WhichModel) -> &'static str {
} }
} }
/// List all supported models
fn run_list() -> anyhow::Result<()> {
let models = [
WhichModel::MiniCPM4_0_5B,
WhichModel::Qwen2_5vl3B,
WhichModel::Qwen2_5vl7B,
WhichModel::Qwen3_0_6B,
WhichModel::Qwen3vl2B,
WhichModel::Qwen3vl4B,
WhichModel::Qwen3vl8B,
WhichModel::Qwen3vl32B,
WhichModel::DeepSeekOCR,
WhichModel::HunyuanOCR,
WhichModel::PaddleOCRVL,
WhichModel::RMBG2_0,
WhichModel::VoxCPM,
WhichModel::VoxCPM1_5,
WhichModel::GlmASRNano2512,
WhichModel::FunASRNano2512,
];
println!("Available models:");
println!();
println!("{:<30} {}", "Model Name", "ModelScope ID");
println!("{}", "-".repeat(80));
for model in models {
let possible_value = model.to_possible_value().unwrap();
let name = possible_value.get_name();
let id = get_model_id(model);
println!("{:<30} {}", name, id);
}
Ok(())
}
/// Run the 'cli' subcommand: download model (if needed) and start service /// Run the 'cli' subcommand: download model (if needed) and start service
async fn run_cli(args: CliArgs) -> anyhow::Result<()> { async fn run_cli(args: CliArgs) -> anyhow::Result<()> {
let CliArgs { common, weight_path, save_dir, download_retries } = args; let CliArgs { common, weight_path, save_dir, download_retries } = args;
@@ -329,6 +366,7 @@ async fn main() -> anyhow::Result<()> {
Some(Commands::Serv(args)) => run_serv(args).await, Some(Commands::Serv(args)) => run_serv(args).await,
Some(Commands::Download(args)) => run_download(args).await, Some(Commands::Download(args)) => run_download(args).await,
Some(Commands::Run(args)) => run_run(args), Some(Commands::Run(args)) => run_run(args),
Some(Commands::List) => run_list(),
None => { None => {
// Backward compatibility: when no subcommand is provided, use 'cli' behavior // Backward compatibility: when no subcommand is provided, use 'cli' behavior
let model = cli.model.expect("Model is required (use -m or --model)"); let model = cli.model.expect("Model is required (use -m or --model)");
+16 -16
View File
@@ -29,37 +29,37 @@ use crate::models::{
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)] #[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum WhichModel { pub enum WhichModel {
#[value(name = "minicpm4-0.5b")] #[value(name = "minicpm4-0.5b", hide = true)]
MiniCPM4_0_5B, MiniCPM4_0_5B,
#[value(name = "qwen2.5vl-3b")] #[value(name = "qwen2.5vl-3b", hide = true)]
Qwen2_5vl3B, Qwen2_5vl3B,
#[value(name = "qwen2.5vl-7b")] #[value(name = "qwen2.5vl-7b", hide = true)]
Qwen2_5vl7B, Qwen2_5vl7B,
#[value(name = "qwen3-0.6b")] #[value(name = "qwen3-0.6b", hide = true)]
Qwen3_0_6B, Qwen3_0_6B,
#[value(name = "qwen3vl-2b")] #[value(name = "qwen3vl-2b", hide = true)]
Qwen3vl2B, Qwen3vl2B,
#[value(name = "qwen3vl-4b")] #[value(name = "qwen3vl-4b", hide = true)]
Qwen3vl4B, Qwen3vl4B,
#[value(name = "qwen3vl-8b")] #[value(name = "qwen3vl-8b", hide = true)]
Qwen3vl8B, Qwen3vl8B,
#[value(name = "qwen3vl-32b")] #[value(name = "qwen3vl-32b", hide = true)]
Qwen3vl32B, Qwen3vl32B,
#[value(name = "deepseek-ocr")] #[value(name = "deepseek-ocr", hide = true)]
DeepSeekOCR, DeepSeekOCR,
#[value(name = "hunyuan-ocr")] #[value(name = "hunyuan-ocr", hide = true)]
HunyuanOCR, HunyuanOCR,
#[value(name = "paddleocr-vl")] #[value(name = "paddleocr-vl", hide = true)]
PaddleOCRVL, PaddleOCRVL,
#[value(name = "RMBG2.0")] #[value(name = "RMBG2.0", hide = true)]
RMBG2_0, RMBG2_0,
#[value(name = "voxcpm")] #[value(name = "voxcpm", hide = true)]
VoxCPM, VoxCPM,
#[value(name = "voxcpm1.5")] #[value(name = "voxcpm1.5", hide = true)]
VoxCPM1_5, VoxCPM1_5,
#[value(name = "glm-asr-nano-2512")] #[value(name = "glm-asr-nano-2512", hide = true)]
GlmASRNano2512, GlmASRNano2512,
#[value(name = "fun-asr-nano-2512")] #[value(name = "fun-asr-nano-2512", hide = true)]
FunASRNano2512, FunASRNano2512,
} }