2727#include < cinttypes>
2828#include < climits>
2929#include < cstdarg>
30+ #include < filesystem>
3031#include < fstream>
3132#include < list>
3233#include < regex>
@@ -487,12 +488,15 @@ void common_models_handler_apply(common_models_handler & handler, common_params
487488 task.opts = opts;
488489 tasks.push_back (task);
489490 }
491+
492+ bool had_spec_url = false ;
490493 if (!params.speculative .draft .mparams .url .empty ()) {
491494 common_download_task task;
492495 task.url = params.speculative .draft .mparams .url ;
493496 task.local_path = params.speculative .draft .mparams .path ;
494497 task.opts = opts;
495498 tasks.push_back (task);
499+ had_spec_url = true ;
496500 }
497501
498502 // handle hf_plan tasks
@@ -512,6 +516,18 @@ void common_models_handler_apply(common_models_handler & handler, common_params
512516 });
513517 }
514518 };
519+
520+ // handle plan_spec (e.g. --spec-draft-hf)
521+ if (!plan_spec.model_files .empty () && !had_spec_url) {
522+ add_tasks (plan_spec.model_files , plan_spec.primary , params.speculative .draft .mparams );
523+ had_spec_url = true ;
524+ }
525+
526+ // handle vocoder plan (e.g. --hf-repo-v)
527+ if (!plan_voc.model_files .empty ()) {
528+ add_tasks (plan_voc.model_files , plan_voc.primary , params.vocoder .model );
529+ }
530+
515531 if (!plan.model_files .empty ()) {
516532 add_tasks (plan.model_files , plan.primary , params.model );
517533 }
@@ -520,7 +536,7 @@ void common_models_handler_apply(common_models_handler & handler, common_params
520536 params.mmproj .path = hf_cache::finalize_file (plan.mmproj );
521537 });
522538 }
523- if (!plan.mtp .local_path .empty ()) {
539+ if (!plan.mtp .local_path .empty () && !had_spec_url ) {
524540 tasks.emplace_back (plan.mtp , opts, [&]() {
525541 // only fall back to the discovered MTP head when no draft was explicitly provided
526542 if (params.speculative .draft .mparams .empty ()) {
@@ -539,16 +555,6 @@ void common_models_handler_apply(common_models_handler & handler, common_params
539555 });
540556 }
541557
542- // handle plan_spec (e.g. --spec-draft-hf)
543- if (!plan_spec.model_files .empty ()) {
544- add_tasks (plan_spec.model_files , plan_spec.primary , params.speculative .draft .mparams );
545- }
546-
547- // handle vocoder plan (e.g. --hf-repo-v)
548- if (!plan_voc.model_files .empty ()) {
549- add_tasks (plan_voc.model_files , plan_voc.primary , params.vocoder .model );
550- }
551-
552558 // run all tasks in parallel
553559 if (!params.offline ) {
554560 // if duplicated files are found, only download once (but still call on_done for each task)
@@ -561,6 +567,7 @@ void common_models_handler_apply(common_models_handler & handler, common_params
561567 }
562568 std::vector<common_download_task> unique_tasks_vec;
563569 for (auto & pair : unique_tasks) {
570+ LOG_DBG (" download task: %s -> %s\n " , pair.second ->url .c_str (), pair.second ->local_path .c_str ());
564571 unique_tasks_vec.push_back (*pair.second );
565572 }
566573 common_download_run_tasks (unique_tasks_vec);
@@ -718,9 +725,8 @@ static bool common_params_parse_ex(int argc, char ** argv, common_params_context
718725
719726 // model is required (except for server)
720727 // TODO @ngxson : maybe show a list of available models in CLI in this case
721- if (params.model .path .empty ()
722- && !params.usage
723- && !params.completion ) {
728+ bool can_skip_model = params.usage || params.completion || !params.server_base .empty ();
729+ if (!can_skip_model && params.model .path .empty ()) {
724730 throw std::invalid_argument (" error: --model is required\n " );
725731 }
726732 }
@@ -1240,6 +1246,13 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
12401246 params.completion = true ;
12411247 }
12421248 ));
1249+ add_opt (common_arg (
1250+ {" --server-base" }, " URL" ,
1251+ string_format (" connect to this server instead of starting a new one, example: 'http://localhost:8080' (default: none)" ),
1252+ [](common_params & params, const std::string & value) {
1253+ params.server_base = value;
1254+ }
1255+ ).set_examples ({LLAMA_EXAMPLE_CLI }));
12431256 add_opt (common_arg (
12441257 {" --verbose-prompt" },
12451258 string_format (" print a verbose prompt before generation (default: %s)" , params.verbose_prompt ? " true" : " false" ),
@@ -2842,7 +2855,7 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
28422855 params.out_file = value;
28432856 }
28442857 ).set_examples ({LLAMA_EXAMPLE_IMATRIX , LLAMA_EXAMPLE_CVECTOR_GENERATOR , LLAMA_EXAMPLE_EXPORT_LORA , LLAMA_EXAMPLE_TTS , LLAMA_EXAMPLE_FINETUNE ,
2845- LLAMA_EXAMPLE_RESULTS , LLAMA_EXAMPLE_EXPORT_GRAPH_OPS }));
2858+ LLAMA_EXAMPLE_RESULTS , LLAMA_EXAMPLE_EXPORT_GRAPH_OPS , LLAMA_EXAMPLE_CLI }));
28462859 add_opt (common_arg (
28472860 {" -ofreq" , " --output-frequency" }, " N" ,
28482861 string_format (" output the imatrix every N iterations (default: %d)" , params.n_out_freq ),
@@ -3029,7 +3042,7 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
30293042 {" --tools" }, " TOOL1,TOOL2,..." ,
30303043 " experimental: whether to enable built-in tools for AI agents - do not enable in untrusted environments (default: no tools)\n "
30313044 " specify \" all\" to enable all tools\n "
3032- " available tools: read_file, file_glob_search, grep_search, exec_shell_command, write_file, edit_file, apply_diff, get_datetime" ,
3045+ " available tools: read_file, file_glob_search, grep_search, exec_shell_command, write_file, edit_file, get_datetime" ,
30333046 [](common_params & params, const std::string & value) {
30343047 params.server_tools = parse_csv_row (value);
30353048 }
@@ -3451,9 +3464,14 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
34513464 ).set_env (" LLAMA_ARG_LOG_FILE" ));
34523465 add_opt (common_arg (
34533466 {" --log-prompts-dir" }, " PATH" ,
3454- " Log prompts to directory (only used for debugging, default: disabled)" ,
3467+ " Log prompts to directory (auto-created if not present; only used for debugging, default: disabled)" ,
34553468 [](common_params & params, const std::string & value) {
34563469 params.path_prompts_log_dir = value;
3470+ std::error_code ec;
3471+ std::filesystem::create_directories (value, ec);
3472+ if (ec) {
3473+ fprintf (stderr, " warning: failed to create prompts-log-dir '%s': %s\n " , value.c_str (), ec.message ().c_str ());
3474+ }
34573475 }
34583476 ).set_examples ({LLAMA_EXAMPLE_SERVER , LLAMA_EXAMPLE_CLI }));
34593477 add_opt (common_arg (
0 commit comments