Skip to content
This repository was archived by the owner on Jul 4, 2025. It is now read-only.

Commit fa045c8

Browse files
committed
feat: add support for Model and Engine service
1 parent 1db9cad commit fa045c8

File tree

8 files changed

+86
-68
lines changed

8 files changed

+86
-68
lines changed
Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
#include "engine_install_cmd.h"
2-
// clang-format off
3-
#include "utils/cortexso_parser.h"
4-
#include "utils/archive_utils.h"
5-
// clang-format on
6-
#include "utils/cuda_toolkit_utils.h"
7-
#include "utils/engine_matcher_utils.h"
82
#include "utils/logging_utils.h"
93

104
namespace commands {
115

126
void EngineInstallCmd::Exec(const std::string& engine,
137
const std::string& version,
148
const std::string& src) {
15-
engine_service_.InstallEngine(engine, version, src);
16-
CLI_LOG("Engine " << engine << " installed successfully!");
9+
auto result = engine_service_.InstallEngine(engine, version, src);
10+
if (result.has_error()) {
11+
CLI_LOG(result.error());
12+
} else {
13+
CLI_LOG("Engine " << engine << " installed successfully!");
14+
}
1715
}
1816
}; // namespace commands

engine/commands/engine_uninstall_cmd.cc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55
namespace commands {
66

77
void EngineUninstallCmd::Exec(const std::string& engine) {
8-
engine_service_.UninstallEngine(engine);
9-
CLI_LOG("Engine " << engine << " uninstalled successfully!");
8+
auto result = engine_service_.UninstallEngine(engine);
9+
10+
if (result.has_error()) {
11+
CLI_LOG(result.error());
12+
} else {
13+
CLI_LOG("Engine uninstalled successfully");
14+
}
1015
}
1116
}; // namespace commands

engine/commands/run_cmd.cc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
#include "run_cmd.h"
22
#include "chat_cmd.h"
3-
#include "cmd_info.h"
43
#include "config/yaml_config.h"
54
#include "model_start_cmd.h"
65
#include "model_status_cmd.h"
76
#include "server_start_cmd.h"
8-
#include "utils/cortex_utils.h"
9-
#include "utils/file_manager_utils.h"
7+
#include "utils/logging_utils.h"
108
#include "utils/modellist_utils.h"
9+
1110
namespace commands {
1211

1312
void RunCmd::Exec() {
@@ -45,7 +44,10 @@ void RunCmd::Exec() {
4544
throw std::runtime_error("Engine " + mc.engine + " is incompatible");
4645
}
4746
if (required_engine.value().status == EngineService::kNotInstalled) {
48-
engine_service_.InstallEngine(mc.engine);
47+
auto install_engine_result = engine_service_.InstallEngine(mc.engine);
48+
if (install_engine_result.has_error()) {
49+
throw std::runtime_error(install_engine_result.error());
50+
}
4951
}
5052
}
5153

engine/services/download_service.cc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "download_service.h"
1111
#include "utils/format_utils.h"
1212
#include "utils/logging_utils.h"
13+
#include "utils/result.hpp"
1314

1415
#ifdef _WIN32
1516
#define ftell64(f) _ftelli64(f)
@@ -26,7 +27,7 @@ size_t WriteCallback(void* ptr, size_t size, size_t nmemb, FILE* stream) {
2627
}
2728
} // namespace
2829

29-
void DownloadService::AddDownloadTask(
30+
cpp::result<void, std::string> DownloadService::AddDownloadTask(
3031
DownloadTask& task, std::optional<OnDownloadTaskSuccessfully> callback) {
3132
CLI_LOG("Validating download items, please wait..");
3233
// preprocess to check if all the item are valid
@@ -45,7 +46,7 @@ void DownloadService::AddDownloadTask(
4546

4647
if (err_msg.has_value()) {
4748
CTL_ERR(err_msg.value());
48-
return;
49+
return cpp::fail(err_msg.value());
4950
}
5051

5152
// all items are valid, start downloading
@@ -62,12 +63,13 @@ void DownloadService::AddDownloadTask(
6263
}
6364
if (dl_err_msg.has_value()) {
6465
CTL_ERR(dl_err_msg.value());
65-
return;
66+
return cpp::fail(dl_err_msg.value());
6667
}
6768

6869
if (callback.has_value()) {
6970
callback.value()(task);
7071
}
72+
return {};
7173
}
7274

7375
cpp::result<uint64_t, std::string> DownloadService::GetFileSize(

engine/services/download_service.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class DownloadService {
5757
using OnDownloadTaskSuccessfully =
5858
std::function<void(const DownloadTask& task)>;
5959

60-
void AddDownloadTask(
60+
cpp::result<void, std::string> AddDownloadTask(
6161
DownloadTask& task,
6262
std::optional<OnDownloadTaskSuccessfully> callback = std::nullopt);
6363

engine/services/engine_service.cc

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#include "engine_service.h"
22
#include <httplib.h>
3-
#include <stdexcept>
43
#include "algorithm"
54
#include "utils/archive_utils.h"
65
#include "utils/engine_matcher_utils.h"
76
#include "utils/file_manager_utils.h"
87
#include "utils/json.hpp"
8+
#include "utils/result.hpp"
99
#include "utils/semantic_version_utils.h"
1010
#include "utils/system_info_utils.h"
1111
#include "utils/url_parser.h"
@@ -40,7 +40,6 @@ EngineService::~EngineService() {}
4040

4141
std::optional<EngineInfo> EngineService::GetEngineInfo(
4242
const std::string& engine) const {
43-
// if engine is not found in kSupportEngine, throw runtime error
4443
if (std::find(kSupportEngines.begin(), kSupportEngines.end(), engine) ==
4544
kSupportEngines.end()) {
4645
return std::nullopt;
@@ -99,21 +98,24 @@ std::vector<EngineInfo> EngineService::GetEngineInfoList() const {
9998
return engines;
10099
}
101100

102-
void EngineService::InstallEngine(const std::string& engine,
103-
const std::string& version,
104-
const std::string& src) {
101+
cpp::result<void, std::string> EngineService::InstallEngine(
102+
const std::string& engine, const std::string& version,
103+
const std::string& src) {
105104

106105
if (!src.empty()) {
107-
UnzipEngine(engine, version, src);
106+
return UnzipEngine(engine, version, src);
108107
} else {
109-
DownloadEngine(engine, version);
110-
DownloadCuda(engine);
108+
auto result = DownloadEngine(engine, version);
109+
if (result.has_error()) {
110+
return result;
111+
}
112+
return DownloadCuda(engine);
111113
}
112114
}
113115

114-
void EngineService::UnzipEngine(const std::string& engine,
115-
const std::string& version,
116-
const std::string& path) {
116+
cpp::result<void, std::string> EngineService::UnzipEngine(
117+
const std::string& engine, const std::string& version,
118+
const std::string& path) {
117119
bool found_cuda = false;
118120

119121
CTL_INF("engine: " << engine);
@@ -150,9 +152,8 @@ void EngineService::UnzipEngine(const std::string& engine,
150152
}
151153
}
152154
} else {
153-
// Folder does not exist, throw exception
154-
CTL_ERR("Folder does not exist: " << path);
155-
return;
155+
// Folder does not exist
156+
return cpp::fail("Folder does not exist: " + path);
156157
}
157158

158159
auto matched_variant = GetMatchedVariant(engine, variants);
@@ -162,7 +163,7 @@ void EngineService::UnzipEngine(const std::string& engine,
162163
<< hw_inf_.sys_inf->arch
163164
<< ", will get engine from remote");
164165
// Go with the remote flow
165-
DownloadEngine(engine, version);
166+
return DownloadEngine(engine, version);
166167
} else {
167168
auto engine_path = file_manager_utils::GetEnginesContainerPath();
168169
archive_utils::ExtractArchive(path + "/" + matched_variant,
@@ -171,33 +172,33 @@ void EngineService::UnzipEngine(const std::string& engine,
171172

172173
// Not match any cuda binary, download from remote
173174
if (!found_cuda) {
174-
DownloadCuda(engine);
175+
return DownloadCuda(engine);
175176
}
176-
}
177-
178-
void EngineService::UninstallEngine(const std::string& engine) {
179-
// TODO: Unload the model which is currently running on engine_
180177

181-
// TODO: Unload engine if is loaded
178+
return {};
179+
}
182180

181+
cpp::result<void, std::string> EngineService::UninstallEngine(
182+
const std::string& engine) {
183183
auto ecp = file_manager_utils::GetEnginesContainerPath();
184184
auto engine_path = ecp / engine;
185185

186186
if (!std::filesystem::exists(engine_path)) {
187-
throw std::runtime_error("Engine " + engine + " is not installed!");
187+
return cpp::fail("Engine " + engine + " is not installed!");
188188
}
189189

190190
try {
191191
std::filesystem::remove_all(engine_path);
192192
CTL_INF("Engine " << engine << " uninstalled successfully!");
193+
return {};
193194
} catch (const std::exception& e) {
194195
CTL_ERR("Failed to uninstall engine " << engine << ": " << e.what());
195-
throw;
196+
return cpp::fail("Failed to uninstall engine " + engine + ": " + e.what());
196197
}
197198
}
198199

199-
void EngineService::DownloadEngine(const std::string& engine,
200-
const std::string& version) {
200+
cpp::result<void, std::string> EngineService::DownloadEngine(
201+
const std::string& engine, const std::string& version) {
201202
auto get_params = [&engine, &version]() -> std::vector<std::string> {
202203
if (version == "latest") {
203204
return {"repos", "janhq", engine, "releases", version};
@@ -231,7 +232,7 @@ void EngineService::DownloadEngine(const std::string& engine,
231232
body = get_data(body);
232233
}
233234
if (body.empty()) {
234-
throw std::runtime_error("No release found for " + version);
235+
return cpp::fail("No release found for " + version);
235236
}
236237

237238
auto assets = body["assets"];
@@ -249,7 +250,7 @@ void EngineService::DownloadEngine(const std::string& engine,
249250
CTL_INF("Matched variant: " << matched_variant);
250251
if (matched_variant.empty()) {
251252
CTL_ERR("No variant found for " << os_arch);
252-
throw std::runtime_error("No variant found for " + os_arch);
253+
return cpp::fail("No variant found for " + os_arch);
253254
}
254255

255256
for (auto& asset : assets) {
@@ -280,8 +281,7 @@ void EngineService::DownloadEngine(const std::string& engine,
280281
.localPath = local_path,
281282
}}}};
282283

283-
DownloadService download_service;
284-
download_service.AddDownloadTask(
284+
return DownloadService().AddDownloadTask(
285285
downloadTask, [](const DownloadTask& finishedTask) {
286286
// try to unzip the downloaded file
287287
CTL_INF("Engine zip path: "
@@ -302,23 +302,24 @@ void EngineService::DownloadEngine(const std::string& engine,
302302
}
303303
CTL_INF("Finished!");
304304
});
305-
return;
306305
}
307306
}
307+
return {};
308308
} else {
309-
throw std::runtime_error("Failed to fetch engine release: " + engine);
309+
return cpp::fail("Failed to fetch engine release: " + engine);
310310
}
311311
}
312312

313-
void EngineService::DownloadCuda(const std::string& engine) {
313+
cpp::result<void, std::string> EngineService::DownloadCuda(
314+
const std::string& engine) {
314315
if (hw_inf_.sys_inf->os == "mac" || engine == "cortex.onnx") {
315316
// mac and onnx engine does not require cuda toolkit
316-
return;
317+
return {};
317318
}
318319

319320
if (hw_inf_.cuda_driver_version.empty()) {
320321
CTL_WRN("No cuda driver, continue with CPU");
321-
return;
322+
return {};
322323
}
323324
// download cuda toolkit
324325
const std::string jan_host = "catalog.jan.ai";
@@ -336,7 +337,7 @@ void EngineService::DownloadCuda(const std::string& engine) {
336337
<< hw_inf_.cuda_driver_version
337338
<< " is not compatible with cuda toolkit version "
338339
<< suitable_toolkit_version);
339-
throw std::runtime_error("Cuda driver is not compatible with cuda toolkit");
340+
return cpp::fail("Cuda driver is not compatible with cuda toolkit");
340341
}
341342

342343
auto url_obj = url_parser::Url{
@@ -362,8 +363,7 @@ void EngineService::DownloadCuda(const std::string& engine) {
362363
.localPath = cuda_toolkit_local_path}},
363364
}};
364365

365-
DownloadService download_service;
366-
download_service.AddDownloadTask(
366+
return DownloadService().AddDownloadTask(
367367
downloadCudaToolkitTask, [&](const DownloadTask& finishedTask) {
368368
auto engine_path =
369369
file_manager_utils::GetEnginesContainerPath() / engine;
@@ -395,4 +395,4 @@ std::string EngineService::GetMatchedVariant(
395395
hw_inf_.cuda_driver_version);
396396
}
397397
return matched_variant;
398-
}
398+
}

engine/services/engine_service.h

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <string_view>
77
#include <vector>
88
#include "utils/cpuid/cpu_info.h"
9+
#include "utils/result.hpp"
910

1011
struct EngineInfo {
1112
std::string name;
@@ -35,19 +36,21 @@ class EngineService {
3536

3637
std::vector<EngineInfo> GetEngineInfoList() const;
3738

38-
void InstallEngine(const std::string& engine,
39-
const std::string& version = "latest",
40-
const std::string& src = "");
39+
cpp::result<void, std::string> InstallEngine(
40+
const std::string& engine, const std::string& version = "latest",
41+
const std::string& src = "");
4142

42-
void UnzipEngine(const std::string& engine, const std::string& version,
43-
const std::string& path);
44-
45-
void UninstallEngine(const std::string& engine);
43+
cpp::result<void, std::string> UninstallEngine(const std::string& engine);
4644

4745
private:
48-
void DownloadEngine(const std::string& engine,
49-
const std::string& version = "latest");
50-
void DownloadCuda(const std::string& engine);
46+
cpp::result<void, std::string> UnzipEngine(const std::string& engine,
47+
const std::string& version,
48+
const std::string& path);
49+
50+
cpp::result<void, std::string> DownloadEngine(
51+
const std::string& engine, const std::string& version = "latest");
52+
53+
cpp::result<void, std::string> DownloadCuda(const std::string& engine);
5154

5255
std::string GetMatchedVariant(const std::string& engine,
5356
const std::vector<std::string>& variants);

engine/services/model_service.cc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,11 @@ std::optional<std::string> ModelService::DownloadModelByDirectUrl(
138138
ParseGguf(gguf_download_item, author);
139139
};
140140

141-
download_service_.AddDownloadTask(downloadTask, on_finished);
141+
auto result = download_service_.AddDownloadTask(downloadTask, on_finished);
142+
if (result.has_error()) {
143+
CTL_ERR(result.error());
144+
return std::nullopt;
145+
}
142146
return unique_model_id;
143147
}
144148

@@ -148,7 +152,7 @@ std::optional<std::string> ModelService::DownloadModelFromCortexso(
148152
auto downloadTask = cortexso_parser::getDownloadTask(name, branch);
149153
if (downloadTask.has_value()) {
150154
std::string model_id{name + ":" + branch};
151-
DownloadService().AddDownloadTask(
155+
auto result = DownloadService().AddDownloadTask(
152156
downloadTask.value(), [&](const DownloadTask& finishedTask) {
153157
const DownloadItem* model_yml_item = nullptr;
154158
auto need_parse_gguf = true;
@@ -179,6 +183,10 @@ std::optional<std::string> ModelService::DownloadModelFromCortexso(
179183
modellist_utils_obj.AddModelEntry(model_entry);
180184
}
181185
});
186+
if (result.has_error()) {
187+
CTL_ERR(result.error());
188+
return std::nullopt;
189+
}
182190

183191
CLI_LOG("Model " << model_id << " downloaded successfully!")
184192
return model_id;

0 commit comments

Comments
 (0)