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

Commit f241d9c

Browse files
committed
Merge branch 'dev' into feat/installer-windows
2 parents 25173dd + a2e54ce commit f241d9c

33 files changed

+912
-209
lines changed

engine/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ if(DEBUG)
5959
add_compile_definitions(ALLOW_ALL_CORS)
6060
endif()
6161

62+
if(NOT DEFINED CORTEX_VARIANT)
63+
set(CORTEX_VARIANT "prod")
64+
endif()
65+
66+
if(NOT DEFINED CORTEX_CONFIG_FILE_PATH)
67+
set(CORTEX_CONFIG_FILE_PATH "user_home")
68+
endif()
69+
6270
if(NOT DEFINED CORTEX_CPP_VERSION)
6371
set(CORTEX_CPP_VERSION "default_version")
6472
endif()
@@ -79,7 +87,9 @@ if(DEFINED CMAKE_JS_INC)
7987
add_compile_definitions(NAPI_VERSION=8)
8088
endif()
8189

90+
add_compile_definitions(CORTEX_VARIANT="${CORTEX_VARIANT}")
8291
add_compile_definitions(CORTEX_CPP_VERSION="${CORTEX_CPP_VERSION}")
92+
add_compile_definitions(CORTEX_CONFIG_FILE_PATH="${CORTEX_CONFIG_FILE_PATH}")
8393

8494
option(CMAKE_BUILD_TEST "Enable testing" OFF)
8595
if(CMAKE_BUILD_TEST)

engine/commands/cortex_upd_cmd.cc

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
// clang-format off
2+
#include "utils/cortex_utils.h"
3+
// clang-format on
4+
#include "cortex_upd_cmd.h"
5+
#include "httplib.h"
6+
#include "nlohmann/json.hpp"
7+
#include "services/download_service.h"
8+
#include "utils/archive_utils.h"
9+
#include "utils/file_manager_utils.h"
10+
#include "utils/logging_utils.h"
11+
#include "utils/system_info_utils.h"
12+
13+
namespace commands {
14+
15+
namespace {
16+
const std::string kCortexBinary = "cortex-cpp";
17+
}
18+
19+
CortexUpdCmd::CortexUpdCmd() {}
20+
21+
void CortexUpdCmd::Exec(std::string v) {
22+
// TODO(sang) stop server if it is running
23+
// Check if the architecture and OS are supported
24+
auto system_info = system_info_utils::GetSystemInfo();
25+
if (system_info.arch == system_info_utils::kUnsupported ||
26+
system_info.os == system_info_utils::kUnsupported) {
27+
CTL_ERR("Unsupported OS or architecture: " << system_info.os << ", "
28+
<< system_info.arch);
29+
return;
30+
}
31+
CTL_INF("OS: " << system_info.os << ", Arch: " << system_info.arch);
32+
33+
// Download file
34+
constexpr auto github_host = "https://api.github.com";
35+
// std::string version = v.empty() ? "latest" : std::move(v);
36+
// TODO(sang): support download with version
37+
std::string version = "latest";
38+
std::ostringstream release_path;
39+
release_path << "/repos/janhq/cortex.cpp/releases/" << version;
40+
CTL_INF("Engine release path: " << github_host << release_path.str());
41+
42+
httplib::Client cli(github_host);
43+
if (auto res = cli.Get(release_path.str())) {
44+
if (res->status == httplib::StatusCode::OK_200) {
45+
try {
46+
auto jsonResponse = nlohmann::json::parse(res->body);
47+
auto assets = jsonResponse["assets"];
48+
auto os_arch{system_info.os + "-" + system_info.arch};
49+
50+
std::string matched_variant = "";
51+
for (auto& asset : assets) {
52+
auto asset_name = asset["name"].get<std::string>();
53+
if (asset_name.find("cortex-cpp") != std::string::npos &&
54+
asset_name.find(os_arch) != std::string::npos) {
55+
matched_variant = asset_name;
56+
break;
57+
}
58+
CTL_INF(asset_name);
59+
}
60+
if (matched_variant.empty()) {
61+
CTL_ERR("No variant found for " << os_arch);
62+
return;
63+
}
64+
CTL_INF("Matched variant: " << matched_variant);
65+
66+
for (auto& asset : assets) {
67+
auto asset_name = asset["name"].get<std::string>();
68+
if (asset_name == matched_variant) {
69+
std::string host{"https://github.com"};
70+
71+
auto full_url = asset["browser_download_url"].get<std::string>();
72+
std::string path = full_url.substr(host.length());
73+
74+
auto fileName = asset["name"].get<std::string>();
75+
CTL_INF("URL: " << full_url);
76+
77+
auto download_task = DownloadTask{.id = "cortex",
78+
.type = DownloadType::Cortex,
79+
.error = std::nullopt,
80+
.items = {DownloadItem{
81+
.id = "cortex",
82+
.host = host,
83+
.fileName = fileName,
84+
.type = DownloadType::Cortex,
85+
.path = path,
86+
}}};
87+
88+
DownloadService download_service;
89+
download_service.AddDownloadTask(
90+
download_task,
91+
[this](const std::string& absolute_path, bool unused) {
92+
// try to unzip the downloaded file
93+
std::filesystem::path download_path{absolute_path};
94+
CTL_INF("Downloaded engine path: " << download_path.string());
95+
96+
std::filesystem::path extract_path =
97+
download_path.parent_path().parent_path();
98+
99+
archive_utils::ExtractArchive(download_path.string(),
100+
extract_path.string());
101+
102+
// remove the downloaded file
103+
// TODO(any) Could not delete file on Windows because it is currently hold by httplib(?)
104+
// Not sure about other platforms
105+
try {
106+
std::filesystem::remove(absolute_path);
107+
} catch (const std::exception& e) {
108+
CTL_WRN("Could not delete file: " << e.what());
109+
}
110+
CTL_INF("Finished!");
111+
});
112+
break;
113+
}
114+
}
115+
} catch (const nlohmann::json::parse_error& e) {
116+
std::cerr << "JSON parse error: " << e.what() << std::endl;
117+
return;
118+
}
119+
} else {
120+
CTL_ERR("HTTP error: " << res->status);
121+
return;
122+
}
123+
} else {
124+
auto err = res.error();
125+
CTL_ERR("HTTP error: " << httplib::to_string(err));
126+
return;
127+
}
128+
#if defined(_WIN32)
129+
auto executable_path = file_manager_utils::GetExecutableFolderContainerPath();
130+
auto temp = executable_path / "cortex_tmp.exe";
131+
remove(temp.string().c_str()); // ignore return code
132+
133+
auto src =
134+
executable_path / "cortex" / kCortexBinary / (kCortexBinary + ".exe");
135+
auto dst = executable_path / (kCortexBinary + ".exe");
136+
// Rename
137+
rename(dst.string().c_str(), temp.string().c_str());
138+
// Update
139+
CopyFile(const_cast<char*>(src.string().c_str()),
140+
const_cast<char*>(dst.string().c_str()), false);
141+
auto download_folder = executable_path / "cortex";
142+
remove(download_folder);
143+
remove(temp.string().c_str());
144+
#else
145+
auto executable_path = file_manager_utils::GetExecutableFolderContainerPath();
146+
auto temp = executable_path / "cortex_tmp";
147+
auto src = executable_path / "cortex" / kCortexBinary / kCortexBinary;
148+
auto dst = executable_path / kCortexBinary;
149+
if (std::rename(dst.string().c_str(), temp.string().c_str())) {
150+
CTL_ERR("Failed to rename from " << dst.string() << " to "
151+
<< temp.string());
152+
return;
153+
}
154+
try {
155+
std::filesystem::copy_file(
156+
src, dst, std::filesystem::copy_options::overwrite_existing);
157+
std::filesystem::permissions(dst, std::filesystem::perms::owner_all |
158+
std::filesystem::perms::group_all |
159+
std::filesystem::perms::others_read |
160+
std::filesystem::perms::others_exec);
161+
std::filesystem::remove(temp);
162+
auto download_folder = executable_path / "cortex/";
163+
std::filesystem::remove_all(download_folder);
164+
} catch (const std::exception& e) {
165+
CTL_WRN("Something wrong happened: " << e.what());
166+
return;
167+
}
168+
#endif
169+
CLI_LOG("Update cortex sucessfully");
170+
}
171+
} // namespace commands

engine/commands/cortex_upd_cmd.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#pragma once
2+
#include <string>
3+
#include <optional>
4+
5+
namespace commands {
6+
7+
class CortexUpdCmd{
8+
public:
9+
CortexUpdCmd();
10+
void Exec(std::string version);
11+
};
12+
13+
} // namespace commands

engine/commands/engine_get_cmd.cc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include "engine_get_cmd.h"
2+
#include <iostream>
3+
#include <tabulate/table.hpp>
4+
#include "services/engine_service.h"
5+
#include "utils/logging_utils.h"
6+
7+
namespace commands {
8+
9+
void EngineGetCmd::Exec() const {
10+
CTL_INF("[EngineGetCmd] engine: " << engine_);
11+
12+
auto engine_service = EngineService();
13+
try {
14+
auto status = engine_service.GetEngineInfo(engine_);
15+
tabulate::Table table;
16+
table.add_row({"name", "description", "version", "product name", "status"});
17+
table.format().font_color(tabulate::Color::green);
18+
table.add_row({status.name, status.description, status.version,
19+
status.product_name, status.status});
20+
std::cout << table << std::endl;
21+
} catch (const std::runtime_error& e) {
22+
std::cerr << "Engine " << engine_ << " is not supported!" << "\n";
23+
} catch (const std::exception& e) {
24+
std::cerr << "Failed to get engine info for " << engine_ << ": " << e.what()
25+
<< "\n";
26+
}
27+
}
28+
}; // namespace commands

engine/commands/engine_get_cmd.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
3+
#include <string>
4+
5+
namespace commands {
6+
class EngineGetCmd {
7+
public:
8+
EngineGetCmd(const std::string& engine) : engine_{engine} {};
9+
10+
void Exec() const;
11+
12+
private:
13+
std::string engine_;
14+
};
15+
} // namespace commands

engine/commands/engine_init_cmd.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ bool EngineInitCmd::Exec() const {
2929
if (system_info.arch == system_info_utils::kUnsupported ||
3030
system_info.os == system_info_utils::kUnsupported) {
3131
CTL_ERR("Unsupported OS or architecture: " << system_info.os << ", "
32-
<< system_info.arch);
32+
<< system_info.arch);
3333
return false;
3434
}
3535
CTL_INF("OS: " << system_info.os << ", Arch: " << system_info.arch);
@@ -192,9 +192,10 @@ bool EngineInitCmd::Exec() const {
192192
// cuda driver version should be greater than toolkit version to ensure compatibility
193193
if (semantic_version_utils::CompareSemanticVersion(
194194
cuda_driver_version, suitable_toolkit_version) < 0) {
195-
CTL_ERR("Your Cuda driver version " << cuda_driver_version
196-
<< " is not compatible with cuda toolkit version "
197-
<< suitable_toolkit_version);
195+
CTL_ERR("Your Cuda driver version "
196+
<< cuda_driver_version
197+
<< " is not compatible with cuda toolkit version "
198+
<< suitable_toolkit_version);
198199
return false;
199200
}
200201

engine/commands/engine_list_cmd.cc

Lines changed: 10 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,24 @@
1-
// clang-format off
2-
#include "utils/cortex_utils.h"
3-
// clang-format on
41
#include "engine_list_cmd.h"
5-
#include <filesystem>
62
#include <tabulate/table.hpp>
7-
#include <utility>
8-
#include "trantor/utils/Logger.h"
3+
#include "services/engine_service.h"
94

105
namespace commands {
116

127
bool EngineListCmd::Exec() {
8+
auto engine_service = EngineService();
9+
auto status_list = engine_service.GetEngineInfoList();
10+
1311
tabulate::Table table;
12+
table.format().font_color(tabulate::Color::green);
1413
table.add_row(
1514
{"(Index)", "name", "description", "version", "product name", "status"});
16-
table.format().font_color(tabulate::Color::green);
17-
#ifdef _WIN32
18-
if (std::filesystem::exists(std::filesystem::current_path().string() +
19-
cortex_utils::kOnnxLibPath)) {
20-
table.add_row({"1", "cortex.onnx",
21-
"This extension enables chat completion API calls using the "
22-
"Onnx engine",
23-
"0.0.1", "Onnx Inference Engine", "ready"});
24-
} else {
25-
table.add_row({"1", "cortex.onnx",
26-
"This extension enables chat completion API calls using the "
27-
"Onnx engine",
28-
"0.0.1", "Onnx Inference Engine", "not_initialized"});
15+
for (int i = 0; i < status_list.size(); i++) {
16+
auto status = status_list[i];
17+
std::string index = std::to_string(i + 1);
18+
table.add_row({index, status.name, status.description, status.version,
19+
status.product_name, status.status});
2920
}
3021

31-
#else
32-
table.add_row(
33-
{"1", "cortex.onnx",
34-
"This extension enables chat completion API calls using the Onnx engine",
35-
"0.0.1", "Onnx Inference Engine", "not_supported"});
36-
#endif
37-
// lllamacpp
38-
if (std::filesystem::exists(std::filesystem::current_path().string() +
39-
cortex_utils::kLlamaLibPath)) {
40-
table.add_row({"2", "cortex.llamacpp",
41-
"This extension enables chat completion API calls using the "
42-
"LlamaCPP engine",
43-
"0.0.1", "LlamaCPP Inference Engine", "ready"});
44-
} else {
45-
table.add_row({"2", "cortex.llamacpp",
46-
"This extension enables chat completion API calls using the "
47-
"LlamaCPP engine",
48-
"0.0.1", "LlamaCPP Inference Engine", "not_initialized"});
49-
}
50-
// tensorrt llm
51-
if (std::filesystem::exists(std::filesystem::current_path().string() +
52-
cortex_utils::kTensorrtLlmPath)) {
53-
table.add_row({"3", "cortex.tensorrt-llm",
54-
"This extension enables chat completion API calls using the "
55-
"TensorrtLLM engine",
56-
"0.0.1", "TensorrtLLM Inference Engine", "ready"});
57-
} else {
58-
table.add_row({"3", "cortex.tensorrt-llm",
59-
"This extension enables chat completion API calls using the "
60-
"TensorrtLLM engine",
61-
"0.0.1", "TensorrtLLM Inference Engine", "not_initialized"});
62-
}
6322
for (int i = 0; i < 6; i++) {
6423
table[0][i]
6524
.format()
@@ -77,5 +36,4 @@ bool EngineListCmd::Exec() {
7736
std::cout << table << std::endl;
7837
return true;
7938
}
80-
8139
}; // namespace commands

engine/commands/engine_list_cmd.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
#pragma once
22

3-
#include <string>
4-
53
namespace commands {
64
class EngineListCmd {
75
public:
8-
bool Exec() ;
6+
bool Exec();
97
};
108

11-
} // namespace commands
9+
} // namespace commands
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include "engine_uninstall_cmd.h"
2+
#include "services/engine_service.h"
3+
#include "utils/logging_utils.h"
4+
5+
namespace commands {
6+
7+
EngineUninstallCmd::EngineUninstallCmd(std::string engine)
8+
: engine_{std::move(engine)} {}
9+
10+
void EngineUninstallCmd::Exec() const {
11+
CTL_INF("Uninstall engine " + engine_);
12+
auto engine_service = EngineService();
13+
14+
try {
15+
engine_service.UninstallEngine(engine_);
16+
CLI_LOG("Engine " << engine_ << " uninstalled successfully!")
17+
} catch (const std::exception& e) {
18+
CLI_LOG("Failed to uninstall engine " << engine_ << ": " << e.what());
19+
}
20+
}
21+
}; // namespace commands

0 commit comments

Comments
 (0)