Skip to content

Add CLI model management commands#9

Draft
Copilot wants to merge 6 commits into
mainfrom
copilot/cli-model-management-commands
Draft

Add CLI model management commands#9
Copilot wants to merge 6 commits into
mainfrom
copilot/cli-model-management-commands

Conversation

Copilot AI commented Jun 24, 2026

Copy link
Copy Markdown

Model setup and recovery were only discoverable through scripts and README instructions. This adds first-class vox model commands for listing, downloading, verifying, repairing, and removing local models.

  • CLI model lifecycle

    • Adds vox model list [--installed]
    • Adds vox model download <model-name>
    • Adds vox model verify <model-name>
    • Adds vox model repair <model-name>
    • Adds vox model remove <model-name>
  • Model manifest and validation

    • Tracks supported local model sets for Qwen3-ASR, Whisper base, HY-MT translation, and CosyVoice3 TTS.
    • Reports model path, version, source, checksum availability, file size, and status.
    • Detects missing, empty, and partial .part downloads.
  • Discoverability

    • Exposes model management from vox --help.
    • Updates missing-model errors to point at vox model download ....
    • Documents the new workflow in the README.

Example:

vox model list
vox model download qwen3-asr-1.7b
vox model verify qwen3-asr-1.7b
vox model repair qwen3-asr-1.7b

Copilot AI changed the title [WIP] Add model management commands for CLI Add CLI model management commands Jun 24, 2026
Copilot AI requested a review from MuoDoo June 24, 2026 03:40
@MuoDoo MuoDoo requested a review from Copilot June 24, 2026 06:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces first-class vox model subcommands to manage local model lifecycle (list/download/verify/repair/remove), centralizing model manifest metadata and status inspection, and updating documentation and tests to cover the new workflow.

Changes:

  • Added a vox_model_manager library implementing model manifest + status inspection and CLI subcommands.
  • Wired vox model ... routing into the main vox CLI and updated missing-model guidance to point at vox model download ....
  • Added README documentation and a new test covering verify/list/remove behavior.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
apps/model_manager.h Declares model manifest/status types and the run_model_command entrypoint.
apps/model_manager.cpp Implements supported model manifest, status inspection, and vox model command handling.
apps/CMakeLists.txt Adds vox_model_manager static library and links it into the vox executable.
apps/vox.cpp Routes vox model ... to the model manager; updates missing-model download hints.
CMakeLists.txt Ensures the apps subdirectory is included so the model manager target exists for tests.
README.md Documents the new model management CLI workflow and verification behavior.
tests/model_manager_test.cpp Adds a focused test for model inspection and vox model subcommands.
tests/CMakeLists.txt Builds and registers the new vox_model_manager_test.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread CMakeLists.txt
Comment on lines 121 to 127
add_subdirectory(llama_runtime)
add_subdirectory(asr)
add_subdirectory(translate)
add_subdirectory(tts)
add_subdirectory(pipeline)
if(VOX_BUILD_APPS)
add_subdirectory(apps)
endif()
add_subdirectory(apps)

Comment thread apps/model_manager.h
Comment thread apps/model_manager.cpp
Comment on lines +239 to +244
for (const ManagedModel & model : supported_models()) {
const ManagedModelStatus status = inspect_model(model, project_root);
if (installed_only && !status.complete) {
continue;
}
out << model.name << "\t" << status_name(status) << "\t" << model.version << "\t";
Comment thread apps/model_manager.cpp
Comment on lines +74 to +81
const int result = std::system(model.download_command.c_str());
std::filesystem::current_path(previous, ec);
if (result != 0) {
err << "Download command failed for " << model.name << ".\n";
return 1;
}
return 0;
}
Comment thread tests/model_manager_test.cpp Outdated
Comment on lines +1 to +24
#include "model_manager.h"

#include <filesystem>
#include <fstream>
#include <iostream>
#include <sstream>

namespace {

bool expect(bool condition, const std::string & message) {
if (!condition) {
std::cerr << message << "\n";
return false;
}
return true;
}

} // namespace

int main() {
namespace fs = std::filesystem;

bool ok = true;
const fs::path root = fs::temp_directory_path() / "vox_model_manager_test";

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Comment thread apps/model_manager.cpp Outdated
Comment thread apps/model_manager.cpp Outdated
Comment on lines +324 to +325
out << "Downloading " << model->name << " using: " << model->download_command << "\n";
return run_download_command(*model, project_root, err);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After a successful download, the model is now re-inspected and a non-zero exit is returned with a clear message when it's still incomplete (410a13e).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Comment thread apps/model_manager.cpp
Comment on lines +301 to +316
if (command == "repair") {
std::error_code ec;
const ManagedModelStatus status = inspect_model(*model, project_root);
for (size_t i = 0; i < model->files.size(); ++i) {
const std::filesystem::path path = status.files[i].path;
if (status.files[i].exists && !status.files[i].complete) {
std::filesystem::remove(path, ec);
if (ec) {
err << "Could not remove incomplete file " << path << ": " << ec.message() << "\n";
return 1;
}
out << "Removed incomplete file: " << path.string() << "\n";
}
std::filesystem::remove(path.string() + ".part", ec);
}
}

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants