Commit 6716df694 for llama.cpp
commit 6716df694ba58b6b5728bf1c675d00909a7da923
Author: Adrien Gallouët <angt@huggingface.co>
Date: Sun Oct 4 10:35:33 2026 +0200
common : prepare load_from_models_dir() for path conversion (#29674)
This is part of the fs::path modernization series.
That was also the opportunity to remove fs_list().
Signed-off-by: Adrien Gallouët <angt@huggingface.co>
diff --git a/common/common.cpp b/common/common.cpp
index a2f162b6f..b69eacc76 100644
--- a/common/common.cpp
+++ b/common/common.cpp
@@ -1033,47 +1033,6 @@ std::filesystem::path fs_get_cache_file(const std::string & filename) {
return cache_directory / std::filesystem::u8path(filename);
}
-std::vector<common_file_info> fs_list(const std::string & path, bool include_directories) {
- std::vector<common_file_info> files;
- if (path.empty()) return files;
-
- std::filesystem::path dir(path);
- if (!std::filesystem::exists(dir) || !std::filesystem::is_directory(dir)) {
- return files;
- }
-
- for (const auto & entry : std::filesystem::directory_iterator(dir)) {
- try {
- // Only include regular files (skip directories)
- const auto & p = entry.path();
- if (std::filesystem::is_regular_file(p)) {
- common_file_info info;
- info.path = p.string();
- info.name = p.filename().string();
- info.is_dir = false;
- try {
- info.size = static_cast<size_t>(std::filesystem::file_size(p));
- } catch (const std::filesystem::filesystem_error &) {
- info.size = 0;
- }
- files.push_back(std::move(info));
- } else if (include_directories && std::filesystem::is_directory(p)) {
- common_file_info info;
- info.path = p.string();
- info.name = p.filename().string();
- info.size = 0; // Directories have no size
- info.is_dir = true;
- files.push_back(std::move(info));
- }
- } catch (const std::filesystem::filesystem_error &) {
- // skip entries we cannot inspect
- continue;
- }
- }
-
- return files;
-}
-
//
// TTY utils
//
diff --git a/common/common.h b/common/common.h
index 4308b0703..6f51675c3 100644
--- a/common/common.h
+++ b/common/common.h
@@ -930,14 +930,6 @@ std::filesystem::path fs_get_cache_directory();
std::filesystem::path fs_get_cache_file(const std::string & filename);
std::filesystem::path fs_get_config_directory();
-struct common_file_info {
- std::string path;
- std::string name;
- size_t size = 0; // in bytes
- bool is_dir = false;
-};
-std::vector<common_file_info> fs_list(const std::string & path, bool include_directories);
-
void fs_write_atomic(const std::filesystem::path & path, const std::string & data);
//
diff --git a/common/preset.cpp b/common/preset.cpp
index 7ca24ec38..14d51809d 100644
--- a/common/preset.cpp
+++ b/common/preset.cpp
@@ -385,63 +385,75 @@ static bool is_draft_file(const std::string & fname) {
}
common_presets common_preset_context::load_from_models_dir(const std::string & models_dir) const {
- if (!std::filesystem::exists(models_dir) || !std::filesystem::is_directory(models_dir)) {
+ const std::filesystem::path dir = std::filesystem::u8path(models_dir);
+ if (!std::filesystem::exists(dir) || !std::filesystem::is_directory(dir)) {
throw std::runtime_error(string_format("error: '%s' does not exist or is not a directory\n", models_dir.c_str()));
}
std::vector<local_model> models;
- auto scan_subdir = [&models](const std::string & subdir_path, const std::string & name) {
- auto files = fs_list(subdir_path, false);
- common_file_info model_file;
- common_file_info first_shard_file;
- common_file_info mmproj_file;
- common_file_info draft_file;
- for (const auto & file : files) {
- if (string_ends_with(file.name, ".gguf")) {
- if (is_mmproj_file(file.name)) {
- mmproj_file = file;
- } else if (is_draft_file(file.name)) {
- if (draft_file.path.empty()) {
- draft_file = file; // first sidecar found wins
- }
- } else if (file.name.find("-00001-of-") != std::string::npos) {
- first_shard_file = file;
- } else {
- model_file = file;
+ auto scan_subdir = [&models](const std::filesystem::path & subdir_path, const std::string & name) {
+ std::filesystem::path model_file;
+ std::filesystem::path first_shard_file;
+ std::filesystem::path mmproj_file;
+ std::filesystem::path draft_file;
+ std::error_code ec;
+ for (const auto & entry : std::filesystem::directory_iterator(subdir_path)) {
+ if (!entry.is_regular_file(ec)) {
+ continue;
+ }
+ const std::string fname = fs_path_to_utf8(entry.path().filename());
+ if (!string_ends_with(fname, ".gguf")) {
+ continue;
+ }
+ if (is_mmproj_file(fname)) {
+ mmproj_file = entry.path();
+ } else if (is_draft_file(fname)) {
+ if (draft_file.empty()) {
+ draft_file = entry.path(); // first sidecar found wins
}
+ } else if (fname.find("-00001-of-") != std::string::npos) {
+ first_shard_file = entry.path();
+ } else {
+ model_file = entry.path();
}
}
// single file model
- local_model model{
- /* name */ name,
- /* path */ first_shard_file.path.empty() ? model_file.path : first_shard_file.path,
- /* path_mmproj */ mmproj_file.path, // can be empty
- /* path_draft */ draft_file.path // can be empty
- };
- if (!model.path.empty()) {
- models.push_back(model);
+ const std::filesystem::path & path = first_shard_file.empty() ? model_file : first_shard_file;
+ if (!path.empty()) {
+ models.push_back({
+ /* name */ name,
+ /* path */ fs_path_to_utf8(path),
+ /* path_mmproj */ fs_path_to_utf8(mmproj_file), // can be empty
+ /* path_draft */ fs_path_to_utf8(draft_file) // can be empty
+ });
}
};
- auto files = fs_list(models_dir, true);
- for (const auto & file : files) {
- if (file.is_dir) {
- scan_subdir(file.path, file.name);
- } else if (string_ends_with(file.name, ".gguf")) {
- if (is_mmproj_file(file.name) || is_draft_file(file.name)) {
- continue; // companion file, cannot be loaded as a model on its own
- }
- // single file model
- std::string name = file.name;
- string_replace_all(name, ".gguf", "");
- local_model model{
- /* name */ name,
- /* path */ file.path,
- /* path_mmproj */ "",
- /* path_draft */ ""
- };
- models.push_back(model);
+ for (const auto & entry : std::filesystem::directory_iterator(dir)) {
+ std::error_code ec;
+ if (entry.is_directory(ec)) {
+ scan_subdir(entry.path(), fs_path_to_utf8(entry.path().filename()));
+ continue;
}
+ if (!entry.is_regular_file(ec)) {
+ continue;
+ }
+ const std::string fname = fs_path_to_utf8(entry.path().filename());
+ if (!string_ends_with(fname, ".gguf")) {
+ continue;
+ }
+ if (is_mmproj_file(fname) || is_draft_file(fname)) {
+ continue; // companion file, cannot be loaded as a model on its own
+ }
+ // single file model
+ std::string name = fname;
+ string_replace_all(name, ".gguf", "");
+ models.push_back({
+ /* name */ name,
+ /* path */ fs_path_to_utf8(entry.path()),
+ /* path_mmproj */ "",
+ /* path_draft */ ""
+ });
}
// convert local models to presets