34namespace entropic::cli {
44std::filesystem::path default_model_dir()
46 if (
const char* env = std::getenv(
"ENTROPIC_MODEL_DIR"); env && *env) {
47 return std::filesystem::path(env);
49 const char* home = std::getenv(
"HOME");
51 return std::filesystem::path(home) /
".entropic" /
"models";
53 return std::filesystem::path(
"/opt/entropic/models");
64 std::printf(
"%-12s %-6s %s\n",
"KEY",
"SIZE",
"DESCRIPTION");
65 std::printf(
"%-12s %-6s %s\n",
"---",
"----",
"-----------");
66 for (
const auto& [key, entry] : registry.entries()) {
67 std::printf(
"%-12s %4.1fGB %s\n",
68 key.c_str(), entry.size_gb, entry.description.c_str());
86int curl_download(
const std::string& url,
const std::filesystem::path& dest)
90 std::fprintf(stderr,
"fork failed\n");
94 execlp(
"curl",
"curl",
101 static_cast<char*
>(
nullptr));
102 std::fprintf(stderr,
"execlp(curl) failed — is curl installed?\n");
106 waitpid(pid, &status, 0);
107 if (WIFEXITED(status)) {
108 return WEXITSTATUS(status);
117 std::filesystem::path override_dir;
118 bool want_list =
false;
131 for (
int i = 1; i < argc; i++) {
132 std::string arg = argv[i];
133 if (arg ==
"--list" || arg ==
"-l") {
134 out.want_list =
true;
135 }
else if (arg ==
"--dir" && i + 1 < argc) {
136 out.override_dir = argv[++i];
137 }
else if (!arg.empty() && arg[0] !=
'-') {
140 std::fprintf(stderr,
"entropic download: unknown option '%s'\n",
157 const auto* entry = registry.
get(key);
160 "entropic download: unknown model key '%s'. "
161 "Run `entropic download --list` for available keys.\n",
165 if (entry->url.empty()) {
167 "entropic download: model '%s' has no URL in the registry.\n",
181 const std::filesystem::path& target_dir,
182 const std::string& key)
186 std::filesystem::create_directories(target_dir, ec);
187 auto target_file = target_dir / (entry.
name +
".gguf");
188 const bool already = std::filesystem::exists(target_file)
189 && std::filesystem::file_size(target_file) > 0;
192 std::fprintf(stderr,
"entropic download: cannot create %s: %s\n",
193 target_dir.c_str(), ec.message().c_str());
195 }
else if (already) {
196 std::printf(
"Model '%s' already at %s — nothing to do.\n",
197 key.c_str(), target_file.c_str());
199 std::printf(
"Downloading %s (%.1f GB)\n from: %s\n to: %s\n",
201 entry.
url.c_str(), target_file.c_str());
202 rc = curl_download(entry.
url, target_file);
205 "entropic download: curl exited with status %d\n"
206 "Partial file left at %s — rerun to resume.\n",
207 rc, target_file.c_str());
209 std::printf(
"\nDone. Point the engine at this dir with:\n"
210 " export ENTROPIC_MODEL_DIR=%s\n",
235 const std::filesystem::path& target_dir)
239 if (mm ==
nullptr) {
return 0; }
240 std::printf(
"Fetching paired mmproj '%s' for vision support\n",
265 if (args.want_list) {
266 rc = list_models(registry);
267 }
else if (args.key.empty()) {
269 "Usage: entropic download <model-key>\n"
270 " entropic download --list\n"
271 " entropic download --dir DIR <model-key>\n");
273 }
else if (
const auto* entry =
resolve_entry(registry, args.key); !entry) {
276 auto target_dir = args.override_dir.empty()
277 ? default_model_dir() : args.override_dir;
278 rc =
fetch_to(*entry, target_dir, args.key);
307 "entropic download: cannot find bundled_models.yaml: %s\n"
308 "(Expected under <install-prefix>/share/entropic/ or the source tree's data/.)\n",
Bundled model registry — resolves keys to filesystem paths.
Bundled model registry loaded from bundled_models.yaml.
std::string auto_discover_and_load()
Auto-discover and load bundled_models.yaml.
const BundledModelEntry * get(const std::string &key) const
Get entry by key.
const entropic::config::BundledModelEntry * resolve_entry(const entropic::config::BundledModels ®istry, const std::string &key)
Resolve a registry entry by key with user-friendly error output.
int fetch_mmproj_if_paired(const entropic::config::BundledModelEntry &entry, const entropic::config::BundledModels ®istry, const std::filesystem::path &target_dir)
Paired-mmproj follow-up fetch (gh#42, v2.1.8).
DownloadArgs parse_download_args(int argc, char *argv[])
Parse command-line args for entropic download.
int run_download(int argc, char *argv[])
Handle entropic download subcommand.
int fetch_to(const entropic::config::BundledModelEntry &entry, const std::filesystem::path &target_dir, const std::string &key)
Download one registry entry to a target directory.
int dispatch(const DownloadArgs &args, const entropic::config::BundledModels ®istry)
Handle entropic download subcommand.
Entry in the bundled model registry.
std::string url
Download URL.
double size_gb
Model size in GB.
std::string mmproj_key
Paired mmproj registry key, or empty (gh#42, v2.1.8).
std::string name
Model filename stem (e.g., "Qwen3.5-35B-A3B-UD-IQ3_XXS")