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

Commit 70caa83

Browse files
committed
Merge branch 'dev' of https://github.com/janhq/cortex.cpp into s/feat/spawn-llama-cpp
2 parents cc2e093 + 9ee8b2b commit 70caa83

31 files changed

+328
-80
lines changed

.github/workflows/cortex-cpp-quality-gate.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ jobs:
149149
if: runner.os == 'Linux'
150150
run: |
151151
cd engine
152+
mkdir -p ~/.config/cortexcpp/
152153
echo "huggingFaceToken: ${{ secrets.HUGGINGFACE_TOKEN_READ }}" > ~/.config/cortexcpp/.cortexrc
153154
echo "gitHubToken: ${{ secrets.PAT_SERVICE_ACCOUNT }}" >> ~/.config/cortexcpp/.cortexrc
154155
# ./build/cortex
@@ -175,6 +176,7 @@ jobs:
175176
if: runner.os == 'Linux'
176177
run: |
177178
cd engine
179+
mkdir -p ~/.config/cortexcpp/
178180
echo "apiServerPort: 3928" > ~/.config/cortexcpp/.cortexrc
179181
echo "huggingFaceToken: ${{ secrets.HUGGINGFACE_TOKEN_READ }}" >> ~/.config/cortexcpp/.cortexrc
180182
echo "gitHubToken: ${{ secrets.PAT_SERVICE_ACCOUNT }}" >> ~/.config/cortexcpp/.cortexrc
@@ -453,6 +455,7 @@ jobs:
453455
if: runner.os == 'Linux'
454456
run: |
455457
cd engine
458+
mkdir -p ~/.config/cortexcpp/
456459
echo "gitHubToken: ${{ secrets.GITHUB_TOKEN }}" > ~/.config/cortexcpp/.cortexrc
457460
# ./build/cortex
458461
cat ~/.config/cortexcpp/.cortexrc
@@ -477,6 +480,7 @@ jobs:
477480
if: runner.os == 'Linux'
478481
run: |
479482
cd engine
483+
mkdir -p ~/.config/cortexcpp/
480484
echo "apiServerPort: 3928" > ~/.config/cortexcpp/.cortexrc
481485
echo "gitHubToken: ${{ secrets.GITHUB_TOKEN }}" > ~/.config/cortexcpp/.cortexrc
482486
# ./build/cortex

docs/docs/architecture/cortexrc.mdx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ Example of the `.cortexrc` file:
4444
```
4545
logFolderPath: /home/<user>/cortexcpp
4646
logLlamaCppPath: ./logs/cortex.log
47-
logTensorrtLLMPath: ./logs/cortex.log
4847
logOnnxPath: ./logs/cortex.log
4948
dataFolderPath: /home/<user>/cortexcpp
5049
maxLogLines: 100000

docs/docusaurus.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ const config: Config = {
476476
},
477477
{
478478
label: "Careers",
479-
href: "https://homebrew.bamboohr.com/careers",
479+
href: "https://menlo.bamboohr.com/careers",
480480
},
481481
],
482482
},

engine/cli/command_line_parser.cc

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ void CommandLineParser::SetupConfigsCommands() {
439439

440440
auto is_empty = true;
441441
for (const auto& [key, value] : config_update_opts_) {
442-
if (!value.empty()) {
442+
if (!value.empty() || CONFIGURATIONS.at(key).allow_empty) {
443443
is_empty = false;
444444
break;
445445
}
@@ -658,36 +658,47 @@ void CommandLineParser::SetupHardwareCommands() {
658658
void CommandLineParser::SetupSystemCommands() {
659659
auto start_cmd = app_.add_subcommand("start", "Start the API server");
660660
start_cmd->group(kSystemGroup);
661-
cml_data_.port = std::stoi(cml_data_.config.apiServerPort);
662-
start_cmd->add_option("-p, --port", cml_data_.port, "Server port to listen");
663-
start_cmd->add_option("--loglevel", cml_data_.log_level,
664-
"Set up log level for server, accepted TRACE, DEBUG, "
665-
"INFO, WARN, ERROR");
666-
if (cml_data_.log_level != "INFO" && cml_data_.log_level != "TRACE" &&
667-
cml_data_.log_level != "DEBUG" && cml_data_.log_level != "WARN" &&
668-
cml_data_.log_level != "ERROR") {
669-
CLI_LOG("Invalid log level: " << cml_data_.log_level
670-
<< ", Set Loglevel to INFO");
671-
cml_data_.log_level = "INFO";
661+
662+
// Add options dynamically
663+
std::vector<std::pair<std::string, std::string>> option_names = {
664+
{"logspath", "The directory where logs are stored"},
665+
{"logsllama", "The directory where llama-cpp engine logs are stored"},
666+
{"logsonnx", "The directory where onnx engine logs are stored"},
667+
{"datapath", "The directory for storing data"},
668+
{"loglines", "Log size limit"},
669+
{"host", "The host IP for the API server"},
670+
{"port", "The port used by the API server"},
671+
{"hf-token", "HuggingFace authentication token"},
672+
{"gh-agent", "Github user agent"},
673+
{"gh-token", "Github authentication token"},
674+
{"cors", "Cross-Origin Resource Sharing"},
675+
{"origins", "Lists allowed origins for CORS requests"},
676+
{"proxy-url", "Proxy URL"},
677+
{"verify-proxy", "SSL verification for client proxy connections"},
678+
{"verify-proxy-host", "SSL verification for host proxy connections"},
679+
{"proxy-username", "Proxy username"},
680+
{"proxy-password", "Proxy password"},
681+
{"no-proxy", "Specifies exceptions for proxy usage"},
682+
{"verify-ssl-peer", "SSL/TLS verification for peer connections"},
683+
{"verify-ssl-host", "SSL/TLS verification for host connections"},
684+
{"ssl-cert-path", "Path to SSL certificates"},
685+
{"ssl-key-path", "Path to SSL and keys"},
686+
{"loglevel", "Log level"}};
687+
cml_data_.server_start_options["loglevel"] = "INFO";
688+
for (const auto& option_name : option_names) {
689+
start_cmd->add_option(
690+
"--" + std::get<0>(option_name),
691+
cml_data_.server_start_options[std::get<0>(option_name)],
692+
std::get<1>(option_name));
672693
}
694+
673695
start_cmd->callback([this] {
674696
if (std::exchange(executed_, true))
675697
return;
676-
if (cml_data_.port != stoi(cml_data_.config.apiServerPort)) {
677-
CTL_INF("apiServerPort changed from " << cml_data_.config.apiServerPort
678-
<< " to " << cml_data_.port);
679-
auto config_path = file_manager_utils::GetConfigurationPath();
680-
cml_data_.config.apiServerPort = std::to_string(cml_data_.port);
681-
auto result =
682-
config_yaml_utils::CortexConfigMgr::GetInstance().DumpYamlConfig(
683-
cml_data_.config, config_path.string());
684-
if (result.has_error()) {
685-
CLI_LOG("Error update " << config_path.string() << result.error());
686-
}
687-
}
698+
688699
commands::ServerStartCmd ssc;
689-
ssc.Exec(cml_data_.config.apiServerHost,
690-
std::stoi(cml_data_.config.apiServerPort), cml_data_.log_level);
700+
ssc.Exec(cml_data_.server_start_options["loglevel"],
701+
cml_data_.server_start_options, cml_data_.config);
691702
});
692703

693704
auto stop_cmd = app_.add_subcommand("stop", "Stop the API server");

engine/cli/command_line_parser.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,12 @@ class CommandLineParser {
6767
bool display_gpu_mode = false;
6868
bool display_available_model = false;
6969
std::string filter = "";
70-
std::string log_level = "INFO";
7170

7271
bool show_menu = false;
7372

74-
int port;
7573
config_yaml_utils::CortexConfig config;
7674
std::unordered_map<std::string, std::string> model_update_options;
75+
std::unordered_map<std::string, std::string> server_start_options;
7776
std::string model_src;
7877
};
7978
CmlData cml_data_;

engine/cli/commands/config_upd_cmd.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ void commands::ConfigUpdCmd::Exec(
5656

5757
auto non_null_opts = std::unordered_map<std::string, std::string>();
5858
for (const auto& [key, value] : options) {
59-
if (value.empty()) {
59+
if (value.empty() && !CONFIGURATIONS.at(key).allow_empty) {
6060
continue;
6161
}
6262
non_null_opts[key] = value;

engine/cli/commands/server_start_cmd.cc

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,171 @@ bool ServerStartCmd::Exec(const std::string& host, int port,
138138
#endif
139139
return true;
140140
}
141+
142+
bool ServerStartCmd::Exec(
143+
const std::optional<std::string>& log_level,
144+
const std::unordered_map<std::string, std::string>& options,
145+
CortexConfig& data) {
146+
for (const auto& [key, value] : options) {
147+
if (!value.empty()) {
148+
UpdateConfig(data, key, value);
149+
}
150+
}
151+
152+
auto config_path = file_manager_utils::GetConfigurationPath();
153+
auto result =
154+
config_yaml_utils::CortexConfigMgr::GetInstance().DumpYamlConfig(
155+
data, config_path.string());
156+
if (result.has_error()) {
157+
CTL_WRN("Error update " << config_path.string() << result.error());
158+
}
159+
return Exec(data.apiServerHost, std::stoi(data.apiServerPort), log_level);
160+
}
161+
162+
void ServerStartCmd::UpdateConfig(CortexConfig& data, const std::string& key,
163+
const std::string& value) {
164+
static const std::unordered_map<
165+
std::string, std::function<void(CortexConfig&, const std::string&,
166+
const std::string&)>>
167+
updaters = {
168+
{"logspath",
169+
[](CortexConfig& data, const std::string&, const std::string& v) {
170+
data.logFolderPath = v;
171+
}},
172+
{"logsllama",
173+
[](CortexConfig& data, const std::string&, const std::string& v) {
174+
data.logLlamaCppPath = v;
175+
}},
176+
{"logsonnx",
177+
[](CortexConfig& data, const std::string&, const std::string& v) {
178+
data.logOnnxPath = v;
179+
}},
180+
{"loglines",
181+
[this](CortexConfig& data, const std::string& k,
182+
const std::string& v) {
183+
UpdateNumericField(k, v, [&data](float f) {
184+
data.maxLogLines = static_cast<int>(f);
185+
});
186+
}},
187+
{"host",
188+
[](CortexConfig& data, const std::string&, const std::string& v) {
189+
data.apiServerHost = v;
190+
}},
191+
{"port",
192+
[](CortexConfig& data, const std::string& k, const std::string& v) {
193+
data.apiServerPort = v;
194+
}},
195+
{"hf-token",
196+
[](CortexConfig& data, const std::string&, const std::string& v) {
197+
data.huggingFaceToken = v;
198+
}},
199+
{"gh-agent",
200+
[](CortexConfig& data, const std::string&, const std::string& v) {
201+
data.gitHubUserAgent = v;
202+
}},
203+
{"gh-token",
204+
[](CortexConfig& data, const std::string&, const std::string& v) {
205+
data.gitHubToken = v;
206+
}},
207+
{"cors",
208+
[this](CortexConfig& data, const std::string& k,
209+
const std::string& v) {
210+
UpdateBooleanField(k, v, [&data](bool b) { data.enableCors = b; });
211+
}},
212+
{"origins",
213+
[this](CortexConfig& data, const std::string& k,
214+
const std::string& v) {
215+
UpdateVectorField(k, v,
216+
[&data](const std::vector<std::string>& orgs) {
217+
data.allowedOrigins = orgs;
218+
});
219+
}},
220+
{"proxy-url",
221+
[](CortexConfig& data, const std::string&, const std::string& v) {
222+
data.proxyUrl = v;
223+
}},
224+
{"verify-proxy",
225+
[this](CortexConfig& data, const std::string& k,
226+
const std::string& v) {
227+
UpdateBooleanField(k, v,
228+
[&data](bool b) { data.verifyProxySsl = b; });
229+
}},
230+
{"verify-proxy-host",
231+
[this](CortexConfig& data, const std::string& k,
232+
const std::string& v) {
233+
UpdateBooleanField(
234+
k, v, [&data](bool b) { data.verifyProxyHostSsl = b; });
235+
}},
236+
{"proxy-username",
237+
[](CortexConfig& data, const std::string&, const std::string& v) {
238+
data.proxyUsername = v;
239+
}},
240+
{"proxy-password",
241+
[](CortexConfig& data, const std::string&, const std::string& v) {
242+
data.proxyPassword = v;
243+
}},
244+
{"no-proxy",
245+
[](CortexConfig& data, const std::string&, const std::string& v) {
246+
data.noProxy = v;
247+
}},
248+
{"verify-ssl-peer",
249+
[this](CortexConfig& data, const std::string& k,
250+
const std::string& v) {
251+
UpdateBooleanField(k, v,
252+
[&data](bool b) { data.verifyPeerSsl = b; });
253+
}},
254+
{"verify-ssl-host",
255+
[this](CortexConfig& data, const std::string& k,
256+
const std::string& v) {
257+
UpdateBooleanField(k, v,
258+
[&data](bool b) { data.verifyHostSsl = b; });
259+
}},
260+
{"ssl-cert-path",
261+
[](CortexConfig& data, const std::string&, const std::string& v) {
262+
data.sslCertPath = v;
263+
}},
264+
{"ssl-key-path",
265+
[](CortexConfig& data, const std::string&, const std::string& v) {
266+
data.sslKeyPath = v;
267+
}},
268+
};
269+
270+
if (auto it = updaters.find(key); it != updaters.end()) {
271+
it->second(data, key, value);
272+
CTL_INF("Updated " << key << " to: " << value);
273+
} else {
274+
CTL_WRN("Warning: Unknown configuration key '" << key << "' ignored.");
275+
}
276+
}
277+
278+
void ServerStartCmd::UpdateVectorField(
279+
const std::string& key, const std::string& value,
280+
std::function<void(const std::vector<std::string>&)> setter) {
281+
std::vector<std::string> tokens;
282+
std::istringstream iss(value);
283+
std::string token;
284+
while (std::getline(iss, token, ',')) {
285+
tokens.push_back(token);
286+
}
287+
setter(tokens);
288+
}
289+
290+
void ServerStartCmd::UpdateNumericField(const std::string& key,
291+
const std::string& value,
292+
std::function<void(float)> setter) {
293+
try {
294+
float numeric_val = std::stof(value);
295+
setter(numeric_val);
296+
} catch (const std::exception& e) {
297+
CLI_LOG("Failed to parse numeric value for " << key << ": " << e.what());
298+
}
299+
}
300+
301+
void ServerStartCmd::UpdateBooleanField(const std::string& key,
302+
const std::string& value,
303+
std::function<void(bool)> setter) {
304+
bool bool_value = (value == "true" || value == "1");
305+
setter(bool_value);
306+
}
307+
141308
}; // namespace commands

engine/cli/commands/server_start_cmd.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
#include <optional>
44
#include <string>
5+
#include "utils/config_yaml_utils.h"
56
#include "utils/curl_utils.h"
67
#include "utils/logging_utils.h"
78
#include "utils/url_parser.h"
89

910
namespace commands {
11+
using CortexConfig = config_yaml_utils::CortexConfig;
1012

1113
inline bool IsServerAlive(const std::string& host, int port) {
1214
auto url = url_parser::Url{
@@ -26,5 +28,23 @@ class ServerStartCmd {
2628
public:
2729
bool Exec(const std::string& host, int port,
2830
const std::optional<std::string>& log_level = std::nullopt);
31+
32+
bool Exec(const std::optional<std::string>& log_level,
33+
const std::unordered_map<std::string, std::string>& options,
34+
CortexConfig& data);
35+
36+
private:
37+
void UpdateConfig(CortexConfig& data, const std::string& key,
38+
const std::string& value);
39+
40+
void UpdateVectorField(
41+
const std::string& key, const std::string& value,
42+
std::function<void(const std::vector<std::string>&)> setter);
43+
44+
void UpdateNumericField(const std::string& key, const std::string& value,
45+
std::function<void(float)> setter);
46+
47+
void UpdateBooleanField(const std::string& key, const std::string& value,
48+
std::function<void(bool)> setter);
2949
};
3050
} // namespace commands

0 commit comments

Comments
 (0)