Commit feb9a3d6d for llama.cpp

commit feb9a3d6debb3a8544052b04c84fa1f445fd77f5
Author: pr3pony <pr3pony@pm.me>
Date:   Thu Oct 1 02:45:39 2026 +0800

    args: fix cli download mmproj arg  (#28977)

    * tests: add tests for cli download arg parsing

    * args: fix cli download mmproj arg

diff --git a/common/arg.cpp b/common/arg.cpp
index 56ca9d3bf..3f01b0259 100644
--- a/common/arg.cpp
+++ b/common/arg.cpp
@@ -387,6 +387,9 @@ common_models_handler common_models_handler_init(const common_params & params, l
             break;
         }
     }
+    if (curr_ex == LLAMA_EXAMPLE_DOWNLOAD) {
+        use_mmproj = true;
+    }

     opts.bearer_token    = params.hf_token;
     opts.offline         = params.offline;
diff --git a/tests/test-model-resolution.cpp b/tests/test-model-resolution.cpp
index 5191e7751..5c793e24a 100644
--- a/tests/test-model-resolution.cpp
+++ b/tests/test-model-resolution.cpp
@@ -344,17 +344,17 @@ static void test_plan_resolution() {
 // loopback, downloads skipped by flipping offline before apply
 //

-static void assemble(std::vector<std::string> argv, common_params & params) {
+static void assemble(std::vector<std::string> argv, common_params & params, llama_example ex = LLAMA_EXAMPLE_SERVER) {
     std::vector<char *> cargv;
     g_context.clear();
     for (auto & a : argv) {
         g_context += g_context.empty() ? a : " " + a;
         cargv.push_back(a.data());
     }
-    bool ok = common_params_parse((int) cargv.size(), cargv.data(), params, LLAMA_EXAMPLE_SERVER);
+    bool ok = common_params_parse((int) cargv.size(), cargv.data(), params, ex);
     REQUIRE(ok);

-    auto handler = common_models_handler_init(params, LLAMA_EXAMPLE_SERVER);
+    auto handler = common_models_handler_init(params, ex);

     // skip the network execution, on_done still wires the params
     params.offline = true;
@@ -382,12 +382,26 @@ static void test_task_assembly() {
         REQUIRE_EQ(params.mmproj.path, cached("test/main", "mmproj-model-Q8_0.gguf"));
         REQUIRE(params.speculative.draft.mparams.path.empty());
     }
+    {
+        // plain -hf wires the model and its mmproj, nothing speculative
+        common_params params;
+        assemble({"download", "-hf", "test/main:Q8_0"}, params, LLAMA_EXAMPLE_DOWNLOAD);
+        REQUIRE_EQ(params.model.path,  cached("test/main", "model-Q8_0.gguf"));
+        REQUIRE_EQ(params.mmproj.path, cached("test/main", "mmproj-model-Q8_0.gguf"));
+        REQUIRE(params.speculative.draft.mparams.path.empty());
+    }
     {
         // --no-mmproj disables the mmproj discovery
         common_params params;
         assemble({"server", "-hf", "test/main:Q8_0", "--no-mmproj"}, params);
         REQUIRE(params.mmproj.path.empty());
     }
+    {
+        // --no-mmproj disables the mmproj discovery
+        common_params params;
+        assemble({"download", "-hf", "test/main:Q8_0", "--no-mmproj"}, params, LLAMA_EXAMPLE_DOWNLOAD);
+        REQUIRE(params.mmproj.path.empty());
+    }
     {
         // an explicit --mmproj wins over the discovery
         common_params params;