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

Commit 027bb54

Browse files
committed
finalizing
1 parent 082e5f4 commit 027bb54

File tree

7 files changed

+83
-126
lines changed

7 files changed

+83
-126
lines changed

engine/cli/commands/engine_release_cmd.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ cpp::result<void, std::string> EngineReleaseCmd::Exec(
7272
github_release_utils::GitHubAsset selected_asset;
7373
for (const auto& asset : selected_release["assets"]) {
7474
if (asset["name"] == variant_selection) {
75-
selected_asset = github_release_utils::GitHubAsset::FromJson(asset);
75+
auto version = string_utils::RemoveSubstring(selection.value(), "v");
76+
selected_asset =
77+
github_release_utils::GitHubAsset::FromJson(asset, version);
7678
break;
7779
}
7880
}

engine/controllers/engines.cc

Lines changed: 5 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -20,42 +20,6 @@ std::string NormalizeEngine(const std::string& engine) {
2020
};
2121
} // namespace
2222

23-
void Engines::InstallEngine(
24-
const HttpRequestPtr& req,
25-
std::function<void(const HttpResponsePtr&)>&& callback,
26-
const std::string& engine) {
27-
28-
if (engine.empty()) {
29-
Json::Value res;
30-
res["message"] = "Engine name is required";
31-
auto resp = cortex_utils::CreateCortexHttpJsonResponse(res);
32-
resp->setStatusCode(k409Conflict);
33-
callback(resp);
34-
LOG_WARN << "No engine field in path param";
35-
return;
36-
}
37-
38-
std::string version = "latest";
39-
if (auto o = req->getJsonObject(); o) {
40-
version = (*o).get("version", "latest").asString();
41-
}
42-
43-
auto result = engine_service_->InstallEngineAsync(engine, version);
44-
if (result.has_error()) {
45-
Json::Value res;
46-
res["message"] = result.error();
47-
auto resp = cortex_utils::CreateCortexHttpJsonResponse(res);
48-
resp->setStatusCode(k400BadRequest);
49-
callback(resp);
50-
} else {
51-
Json::Value res;
52-
res["message"] = "Engine " + engine + " starts installing!";
53-
auto resp = cortex_utils::CreateCortexHttpJsonResponse(res);
54-
resp->setStatusCode(k200OK);
55-
callback(resp);
56-
}
57-
}
58-
5923
void Engines::ListEngine(
6024
const HttpRequestPtr& req,
6125
std::function<void(const HttpResponsePtr&)>&& callback) const {
@@ -167,20 +131,12 @@ void Engines::GetEngineVariants(
167131
void Engines::InstallEngineVariant(
168132
const HttpRequestPtr& req,
169133
std::function<void(const HttpResponsePtr&)>&& callback,
170-
const std::string& engine, const std::string& version,
171-
const std::string& variant_name) {
134+
const std::string& engine, const std::optional<std::string> version,
135+
const std::optional<std::string> variant_name) {
136+
auto normalized_version = version.value_or("latest");
172137

173-
if (version.empty() || variant_name.empty()) {
174-
Json::Value ret;
175-
ret["result"] = "Bad Request";
176-
auto resp = cortex_utils::CreateCortexHttpJsonResponse(ret);
177-
resp->setStatusCode(k400BadRequest);
178-
callback(resp);
179-
return;
180-
}
181-
182-
auto result =
183-
engine_service_->InstallEngineAsyncV2(engine, version, variant_name);
138+
auto result = engine_service_->InstallEngineAsyncV2(
139+
engine, normalized_version, variant_name);
184140
if (result.has_error()) {
185141
Json::Value res;
186142
res["message"] = result.error();

engine/controllers/engines.h

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ class Engines : public drogon::HttpController<Engines, false> {
1212
public:
1313
METHOD_LIST_BEGIN
1414

15-
// TODO: update this API
16-
// METHOD_ADD(Engines::InstallEngine, "/install/{1}", Post);
15+
METHOD_ADD(Engines::InstallEngineVariant, "/{1}?version={2}&variant={3}",
16+
Post);
1717
METHOD_ADD(Engines::UninstallEngine, "/{1}/{2}/{3}", Delete);
1818
METHOD_ADD(Engines::ListEngine, "", Get);
1919

@@ -30,18 +30,13 @@ class Engines : public drogon::HttpController<Engines, false> {
3030
METHOD_ADD(Engines::LoadEngine, "/{1}/load", Post);
3131
METHOD_ADD(Engines::UnloadEngine, "/{1}/load", Delete);
3232

33-
ADD_METHOD_TO(Engines::InstallEngine, "/v1/engines/install/{1}", Post);
3433
ADD_METHOD_TO(Engines::UninstallEngine, "/v1/engines/{1}/{2}/{3}", Delete);
3534

3635
METHOD_LIST_END
3736

3837
explicit Engines(std::shared_ptr<EngineService> engine_service)
3938
: engine_service_{engine_service} {}
4039

41-
void InstallEngine(const HttpRequestPtr& req,
42-
std::function<void(const HttpResponsePtr&)>&& callback,
43-
const std::string& engine);
44-
4540
void ListEngine(const HttpRequestPtr& req,
4641
std::function<void(const HttpResponsePtr&)>&& callback) const;
4742

@@ -62,8 +57,8 @@ class Engines : public drogon::HttpController<Engines, false> {
6257
void InstallEngineVariant(
6358
const HttpRequestPtr& req,
6459
std::function<void(const HttpResponsePtr&)>&& callback,
65-
const std::string& engine, const std::string& version,
66-
const std::string& variant_name);
60+
const std::string& engine, const std::optional<std::string> version,
61+
const std::optional<std::string> variant_name);
6762

6863
void GetEnginesInstalledVariants(
6964
const HttpRequestPtr& req,

engine/services/engine_service.cc

Lines changed: 59 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,12 @@ std::string GetEnginePath(std::string_view e) {
7171

7272
cpp::result<void, std::string> EngineService::InstallEngineAsyncV2(
7373
const std::string& engine, const std::string& version,
74-
const std::string& variant_name) {
74+
const std::optional<std::string> variant_name) {
7575
auto ne = NormalizeEngine(engine);
7676
CTL_INF("InstallEngineAsyncV2: " << ne << ", " << version << ", "
77-
<< variant_name);
77+
<< variant_name.value_or(""));
7878

79-
auto result = DownloadEngineV2(ne, version, variant_name, true /*async*/);
79+
auto result = DownloadEngineV2(ne, version, variant_name);
8080
if (result.has_error()) {
8181
return result;
8282
}
@@ -191,21 +191,11 @@ cpp::result<bool, std::string> EngineService::UninstallEngineVariant(
191191

192192
cpp::result<void, std::string> EngineService::DownloadEngineV2(
193193
const std::string& engine, const std::string& version,
194-
const std::string& variant_name, bool async) {
194+
const std::optional<std::string> variant_name) {
195+
auto normalized_version = version == "latest"
196+
? "latest"
197+
: string_utils::RemoveSubstring(version, "v");
195198

196-
// check if engine variant is installed
197-
bool is_installed = false;
198-
if (is_installed) {
199-
// set default
200-
// TODO: namh implement this
201-
return {};
202-
}
203-
204-
// TODO: namh add back the github_token
205-
206-
auto normalized_version = string_utils::RemoveSubstring(version, "v");
207-
auto merged_variant_name =
208-
engine + "-" + normalized_version + "-" + variant_name + ".tar.gz";
209199
auto res = GetEngineVariants(engine, version);
210200
if (res.has_error()) {
211201
return cpp::fail("Failed to fetch engine releases: " + res.error());
@@ -216,33 +206,70 @@ cpp::result<void, std::string> EngineService::DownloadEngineV2(
216206
}
217207

218208
std::optional<EngineVariant> selected_variant = std::nullopt;
219-
for (const auto& asset : res.value()) {
220-
if (asset.name == merged_variant_name) {
221-
selected_variant = asset;
222-
break;
209+
210+
if (variant_name.has_value()) {
211+
auto merged_variant_name = engine + "-" + normalized_version + "-" +
212+
variant_name.value() + ".tar.gz";
213+
214+
for (const auto& asset : res.value()) {
215+
if (asset.name == merged_variant_name) {
216+
selected_variant = asset;
217+
break;
218+
}
219+
}
220+
} else {
221+
std::vector<std::string> variants;
222+
for (const auto& asset : res.value()) {
223+
variants.push_back(asset.name);
224+
}
225+
226+
auto matched_variant_name = GetMatchedVariant(engine, variants);
227+
for (const auto& v : res.value()) {
228+
if (v.name == matched_variant_name) {
229+
selected_variant = v;
230+
break;
231+
}
223232
}
224233
}
225234

226235
if (selected_variant == std::nullopt) {
227-
return cpp::fail("Not found variant: " + variant_name);
236+
return cpp::fail("Failed to find a suitable variant for " + engine);
228237
}
238+
auto normalize_version = "v" + selected_variant->version;
239+
240+
auto variant_folder_name = engine_matcher_utils::GetVariantFromNameAndVersion(
241+
selected_variant->name, engine, selected_variant->version);
229242

230-
auto engine_folder_path =
231-
file_manager_utils::GetEnginesContainerPath() / engine;
232-
auto variant_folder_path = engine_folder_path / variant_name / version;
233-
auto variant_path = variant_folder_path / merged_variant_name;
243+
auto variant_folder_path = file_manager_utils::GetEnginesContainerPath() /
244+
engine / variant_folder_name.value() /
245+
normalize_version;
246+
247+
auto variant_path = variant_folder_path / selected_variant->name;
234248
std::filesystem::create_directories(variant_folder_path);
235249
CLI_LOG("variant_folder_path: " + variant_folder_path.string());
236-
237-
auto on_finished = [](const DownloadTask& finishedTask) {
250+
auto on_finished = [this, engine, selected_variant,
251+
normalize_version](const DownloadTask& finishedTask) {
238252
// try to unzip the downloaded file
239253
CLI_LOG("Engine zip path: " << finishedTask.items[0].localPath.string());
254+
CLI_LOG("Version: " + normalize_version);
240255

241256
auto extract_path = finishedTask.items[0].localPath.parent_path();
242257

243258
archive_utils::ExtractArchive(finishedTask.items[0].localPath.string(),
244259
extract_path.string(), true);
245260

261+
auto variant = engine_matcher_utils::GetVariantFromNameAndVersion(
262+
selected_variant->name, engine, normalize_version);
263+
CLI_LOG("Extracted variant: " + variant.value());
264+
// set as default
265+
auto res =
266+
SetDefaultEngineVariant(engine, normalize_version, variant.value());
267+
if (res.has_error()) {
268+
CTL_ERR("Failed to set default engine variant: " << res.error());
269+
} else {
270+
CTL_INF("Set default engine variant: " << res.value().variant);
271+
}
272+
246273
// remove the downloaded file
247274
try {
248275
std::filesystem::remove(finishedTask.items[0].localPath);
@@ -270,33 +297,6 @@ cpp::result<void, std::string> EngineService::DownloadEngineV2(
270297

271298
cpp::result<bool, std::string> EngineService::DownloadEngine(
272299
const std::string& engine, const std::string& version, bool async) {
273-
274-
// auto get_params = [&engine, &version]() -> std::vector<std::string> {
275-
// if (version == "latest") {
276-
// return {"repos", "janhq", engine, "releases", version};
277-
// } else {
278-
// return {"repos", "janhq", engine, "releases"};
279-
// }
280-
// };
281-
//
282-
// auto url_obj = url_parser::Url{
283-
// .protocol = "https",
284-
// .host = "api.github.com",
285-
// .pathParams = get_params(),
286-
// };
287-
288-
// std::unordered_map<std::string, std::string> headers;
289-
290-
// Check if GITHUB_TOKEN env exist
291-
// const char* github_token = std::getenv("GITHUB_TOKEN");
292-
// if (github_token) {
293-
// std::string auth_header = "token " + std::string(github_token);
294-
// headers.insert({"Authorization", auth_header});
295-
// CTL_INF("Using authentication with GitHub token.");
296-
// } else {
297-
// CTL_INF("No GitHub token found. Sending request without authentication.");
298-
// }
299-
300300
auto res = GetEngineVariants(engine, version);
301301
if (res.has_error()) {
302302
return cpp::fail("Failed to fetch engine releases: " + res.error());
@@ -335,7 +335,6 @@ cpp::result<bool, std::string> EngineService::DownloadEngine(
335335
CTL_INF("Creating " << engine_folder_path.string());
336336
std::filesystem::create_directories(engine_folder_path);
337337
}
338-
339338
CTL_INF("Engine folder path: " << engine_folder_path.string() << "\n");
340339
auto local_path = engine_folder_path / asset.name;
341340
auto downloadTask{
@@ -549,7 +548,11 @@ cpp::result<bool, std::string> EngineService::IsEngineVariantReady(
549548
auto normalized_version = string_utils::RemoveSubstring(version, "v");
550549
auto installed_engines = GetInstalledEngineVariants(ne);
551550

551+
CLI_LOG("IsEngineVariantReady: " << ne << ", " << normalized_version << ", "
552+
<< variant);
552553
for (const auto& installed_engine : installed_engines) {
554+
CLI_LOG("Installed: name: " + installed_engine.name +
555+
", version: " + installed_engine.version);
553556
if (installed_engine.name == variant &&
554557
installed_engine.version == normalized_version) {
555558
return true;

engine/services/engine_service.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,6 @@ class EngineService {
8282
std::unordered_map<std::string, EngineInfo> engines_{};
8383

8484
public:
85-
constexpr static auto kIncompatible = "Incompatible";
86-
constexpr static auto kReady = "Ready";
87-
constexpr static auto kNotInstalled = "Not Installed";
88-
8985
const std::vector<std::string_view> kSupportEngines = {
9086
kLlamaEngine, kOnnxEngine, kTrtLlmEngine};
9187

@@ -112,8 +108,8 @@ class EngineService {
112108
* If no variant provided, automatically pick the best variant.
113109
*/
114110
cpp::result<void, std::string> InstallEngineAsyncV2(
115-
const std::string& engine, const std::string& version = "latest",
116-
const std::string& variant_name = "");
111+
const std::string& engine, const std::string& version,
112+
const std::optional<std::string> variant_name);
117113

118114
cpp::result<bool, std::string> UninstallEngineVariant(
119115
const std::string& engine, const std::string& variant,
@@ -162,8 +158,8 @@ class EngineService {
162158
bool async = false);
163159

164160
cpp::result<void, std::string> DownloadEngineV2(
165-
const std::string& engine, const std::string& variant,
166-
const std::string& version = "latest", bool async = false);
161+
const std::string& engine, const std::string& version = "latest",
162+
const std::optional<std::string> variant_name = std::nullopt);
167163

168164
cpp::result<bool, std::string> DownloadCuda(const std::string& engine,
169165
bool async = false);

engine/utils/engine_matcher_utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@ inline cpp::result<std::string, std::string> GetVariantFromNameAndVersion(
2424
if (engine.empty()) {
2525
return cpp::fail("Engine name is empty");
2626
}
27+
auto nv = string_utils::RemoveSubstring(version, "v");
2728
using namespace string_utils;
2829
auto removed_extension = RemoveSubstring(engine_file_name, ".tar.gz");
2930
auto version_and_variant = RemoveSubstring(removed_extension, engine + "-");
3031

31-
auto variant = RemoveSubstring(version_and_variant, version + "-");
32+
auto variant = RemoveSubstring(version_and_variant, nv + "-");
3233
return variant;
3334
}
3435

engine/utils/github_release_utils.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ struct GitHubAsset {
2323

2424
std::string updated_at;
2525
std::string browser_download_url;
26+
std::string version;
2627

27-
static GitHubAsset FromJson(const Json::Value& json) {
28+
static GitHubAsset FromJson(const Json::Value& json,
29+
const std::string& version) {
2830
return GitHubAsset{
2931
.url = json["url"].asString(),
3032
.id = json["id"].asInt(),
@@ -38,6 +40,7 @@ struct GitHubAsset {
3840
.created_at = json["created_at"].asString(),
3941
.updated_at = json["updated_at"].asString(),
4042
.browser_download_url = json["browser_download_url"].asString(),
43+
.version = version,
4144
};
4245
}
4346

@@ -55,6 +58,7 @@ struct GitHubAsset {
5558
root["created_at"] = created_at;
5659
root["updated_at"] = updated_at;
5760
root["browser_download_url"] = browser_download_url;
61+
root["version"] = version;
5862
return root;
5963
}
6064

@@ -93,7 +97,7 @@ struct GitHubRelease {
9397
std::vector<GitHubAsset> assets = {};
9498
if (json["assets"].isArray()) {
9599
for (const auto& asset : json["assets"]) {
96-
assets.push_back(GitHubAsset::FromJson(asset));
100+
assets.push_back(GitHubAsset::FromJson(asset, json["name"].asString()));
97101
}
98102
}
99103

0 commit comments

Comments
 (0)