9#include <entropic/entropic_config.h>
19namespace entropic::config {
40std::filesystem::path share_dir_from_library()
43 if (dladdr(
reinterpret_cast<void*
>(&share_dir_from_library), &info) == 0
44 || info.dli_fname ==
nullptr) {
48 auto abs_lib = std::filesystem::absolute(
49 std::filesystem::path(info.dli_fname), ec);
53 return abs_lib.parent_path().parent_path() /
"share" /
"entropic";
82 if (entry.
name.empty()) {
83 return "bundled model '" + entry.
key +
"' missing 'name'";
98 if (content.empty()) {
99 return "cannot read " + path.string();
102 ryml::Tree tree = ryml::parse_in_arena(
103 ryml::to_csubstr(path.string()),
104 ryml::to_csubstr(content));
105 ryml::ConstNodeRef root = tree.rootref();
106 if (!root.is_map()) {
107 return "bundled_models.yaml root is not a mapping";
111 for (
auto child : root) {
114 if (!err.empty()) {
break; }
115 s_log->info(
"Registered bundled model: {} -> {} ({:.1f} GB)",
117 entries_[entry.
key] = std::move(entry);
131 return entries_.count(key) > 0;
143 auto it = entries_.find(key);
144 if (it == entries_.end()) {
162 const std::string& family,
163 const std::string& size_label,
164 const std::string& quant)
const
166 for (
const auto& [key, entry] : entries_) {
167 if (entry.family == family
168 && entry.size_label == size_label
169 && entry.quant == quant) {
201 auto it = entries_.find(value);
202 if (it == entries_.end()) {
206 const auto filename = it->second.name +
".gguf";
207 std::filesystem::path result;
208 const char* reason =
nullptr;
213 if (
const char* env = std::getenv(
"ENTROPIC_MODEL_DIR"); env && *env) {
214 result = std::filesystem::path(env) / filename;
215 reason =
"ENTROPIC_MODEL_DIR";
220 const auto home_path =
221 expand_home(
"~") /
".entropic" /
"models" / filename;
222 const auto sys_path =
223 std::filesystem::path(
"/opt/entropic/models") / filename;
224 if (std::filesystem::is_regular_file(sys_path)
225 && !std::filesystem::is_regular_file(home_path)) {
227 reason =
"/opt/entropic/models";
230 reason = std::filesystem::is_regular_file(home_path)
231 ?
"~/.entropic/models"
232 :
"fallback (file not found)";
236 s_log->info(
"Model '{}' resolved to {} ({})",
237 value, result.string(), reason);
247const std::unordered_map<std::string, BundledModelEntry>&
276 std::vector<std::filesystem::path> candidates;
277 if (
const char* env = std::getenv(
"ENTROPIC_DATA_DIR"); env && *env) {
278 candidates.emplace_back(std::filesystem::path(env) /
"bundled_models.yaml");
280 if (
auto from_lib = share_dir_from_library(); !from_lib.empty()) {
281 candidates.emplace_back(from_lib /
"bundled_models.yaml");
283 candidates.emplace_back(
284 std::filesystem::path(CONFIG_ENTROPIC_DATA_DIR) /
"bundled_models.yaml");
285 candidates.emplace_back(
286 std::filesystem::path(CONFIG_ENTROPIC_SOURCE_DATA_DIR) /
"bundled_models.yaml");
287 candidates.emplace_back(
"data/bundled_models.yaml");
289 for (
const auto& path : candidates) {
290 if (std::filesystem::is_regular_file(path)) {
291 auto err =
load(path);
293 s_log->info(
"pre-loaded {} bundled model(s) from {}",
294 entries_.size(), path.string());
297 s_log->warn(
"bundled models load failed: {} — {}", path.string(), err);
300 return "bundled_models.yaml not found in default paths";
static std::string parse_bundled_entry(ryml::ConstNodeRef child, BundledModelEntry &entry)
Parse one bundled-model YAML entry into entry.
Bundled model registry — resolves keys to filesystem paths.
bool contains(const std::string &key) const
Check if a key exists in the registry.
const std::unordered_map< std::string, BundledModelEntry > & entries() const
Get all entries.
std::string auto_discover_and_load()
Auto-discover and load bundled_models.yaml.
std::filesystem::path resolve(const std::string &value) const
Resolve a model reference to a filesystem path.
std::string find_by(const std::string &family, const std::string &size_label, const std::string &quant) const
Look up a registry key by (family, size, quant) (gh#62).
const BundledModelEntry * get(const std::string &key) const
Get entry by key.
std::string load(const std::filesystem::path &path)
Load registry from YAML file.
spdlog initialization and logger access.
ENTROPIC_EXPORT std::shared_ptr< spdlog::logger > get(const std::string &name)
Get or create a named logger.
Entry in the bundled model registry.
std::string url
Download URL.
std::string size_label
e.g. "0_8b", "2b", "4b", "9b", "e2b", "nano_4b"
std::string key
Registry key (e.g., "primary")
std::string description
Human-readable description.
double size_gb
Model size in GB.
std::string provider
e.g. "unsloth"
std::string mmproj_key
Paired mmproj registry key, or empty (gh#42, v2.1.8).
std::string family
e.g. "qwen3_5", "gemma4", "nemotron3"
std::string quant
e.g. "Q8_0", "Q4_K_M", "UD-IQ4_XS"
std::string name
Model filename stem (e.g., "Qwen3.5-35B-A3B-UD-IQ3_XXS")
std::string adapter
Adapter name (e.g., "qwen35")
std::filesystem::path expand_home(const std::filesystem::path &p)
Expand ~ to home directory in a path.
std::string read_file(const std::filesystem::path &path)
Read a file into a string.
std::string to_string(c4::csubstr s)
Convert ryml csubstr to std::string.
bool extract(ryml::ConstNodeRef node, c4::csubstr key, std::string &out)
Extract a string value from a YAML node.
ryml extraction helpers for config parsing.