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

Commit 3e04350

Browse files
authored
Merge pull request #1546 from janhq/j/engine-management
feat: engine management
2 parents 1becaff + 4b693f5 commit 3e04350

File tree

79 files changed

+3539
-2019
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+3539
-2019
lines changed

docs/static/openapi/cortex.json

Lines changed: 450 additions & 577 deletions
Large diffs are not rendered by default.

engine/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ find_package(jsoncpp CONFIG REQUIRED)
7373
find_package(Drogon CONFIG REQUIRED)
7474
find_package(yaml-cpp CONFIG REQUIRED)
7575
find_package(httplib CONFIG REQUIRED)
76-
find_package(nlohmann_json CONFIG REQUIRED)
7776
find_package(unofficial-minizip CONFIG REQUIRED)
7877
find_package(LibArchive REQUIRED)
7978
find_package(CURL REQUIRED)
@@ -149,7 +148,6 @@ add_executable(${TARGET_NAME} main.cc
149148
target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
150149

151150
target_link_libraries(${TARGET_NAME} PRIVATE httplib::httplib)
152-
target_link_libraries(${TARGET_NAME} PRIVATE nlohmann_json::nlohmann_json)
153151
target_link_libraries(${TARGET_NAME} PRIVATE unofficial::minizip::minizip)
154152
target_link_libraries(${TARGET_NAME} PRIVATE LibArchive::LibArchive)
155153
target_link_libraries(${TARGET_NAME} PRIVATE CURL::libcurl)

engine/cli/CMakeLists.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ add_compile_definitions(CORTEX_CONFIG_FILE_PATH="${CORTEX_CONFIG_FILE_PATH}")
6363
find_package(jsoncpp CONFIG REQUIRED)
6464
find_package(yaml-cpp CONFIG REQUIRED)
6565
find_package(httplib CONFIG REQUIRED)
66-
find_package(nlohmann_json CONFIG REQUIRED)
6766
find_package(CLI11 CONFIG REQUIRED)
6867
find_package(unofficial-minizip CONFIG REQUIRED)
6968
find_package(LibArchive REQUIRED)
@@ -87,7 +86,6 @@ add_executable(${TARGET_NAME} main.cc
8786
)
8887

8988
target_link_libraries(${TARGET_NAME} PRIVATE httplib::httplib)
90-
target_link_libraries(${TARGET_NAME} PRIVATE nlohmann_json::nlohmann_json)
9189
target_link_libraries(${TARGET_NAME} PRIVATE CLI11::CLI11)
9290
target_link_libraries(${TARGET_NAME} PRIVATE unofficial::minizip::minizip)
9391
target_link_libraries(${TARGET_NAME} PRIVATE LibArchive::LibArchive)
@@ -128,4 +126,4 @@ set_target_properties(${TARGET_NAME} PROPERTIES
128126
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}
129127
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}
130128
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
131-
)
129+
)

engine/cli/command_line_parser.cc

Lines changed: 95 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
#include "command_line_parser.h"
22
#include <memory>
33
#include <optional>
4+
#include <string>
45
#include "commands/cortex_upd_cmd.h"
56
#include "commands/engine_get_cmd.h"
67
#include "commands/engine_install_cmd.h"
78
#include "commands/engine_list_cmd.h"
89
#include "commands/engine_uninstall_cmd.h"
9-
#include "commands/model_alias_cmd.h"
10+
#include "commands/engine_update_cmd.h"
11+
#include "commands/engine_use_cmd.h"
1012
#include "commands/model_del_cmd.h"
1113
#include "commands/model_get_cmd.h"
1214
#include "commands/model_import_cmd.h"
@@ -94,8 +96,8 @@ bool CommandLineParser::SetupCommand(int argc, char** argv) {
9496
CLI_LOG("\nNew Cortex release available: "
9597
<< CORTEX_CPP_VERSION << " -> " << *latest_version);
9698
CLI_LOG("To update, run: " << commands::GetRole()
97-
<< commands::GetCortexBinary()
98-
<< " update");
99+
<< commands::GetCortexBinary()
100+
<< " update");
99101
}
100102
done = true;
101103
});
@@ -138,7 +140,8 @@ void CommandLineParser::SetupCommonCommands() {
138140
}
139141
});
140142

141-
auto run_cmd = app_.add_subcommand("run", "Shortcut: pull, start & chat with a model");
143+
auto run_cmd =
144+
app_.add_subcommand("run", "Shortcut: pull, start & chat with a model");
142145
run_cmd->group(kCommonCommandsGroup);
143146
run_cmd->usage("Usage:\n" + commands::GetCortexBinary() +
144147
" run [options] [model_id]");
@@ -270,30 +273,6 @@ void CommandLineParser::SetupModelCommands() {
270273
cml_data_.model_id);
271274
});
272275

273-
std::string model_alias;
274-
auto model_alias_cmd =
275-
models_cmd->add_subcommand("alias", "Add a model alias instead of ID");
276-
model_alias_cmd->usage("Usage:\n" + commands::GetCortexBinary() +
277-
" models alias --model_id [model_id] --alias [alias]");
278-
model_alias_cmd->group(kSubcommands);
279-
model_alias_cmd->add_option(
280-
"--model_id", cml_data_.model_id,
281-
"Can be a model ID or model alias");
282-
model_alias_cmd->add_option("--alias", cml_data_.model_alias,
283-
"new alias to be set");
284-
model_alias_cmd->callback([this, model_alias_cmd]() {
285-
if (std::exchange(executed_, true))
286-
return;
287-
if (cml_data_.model_id.empty() || cml_data_.model_alias.empty()) {
288-
CLI_LOG("[model_id] and [alias] are required\n");
289-
CLI_LOG(model_alias_cmd->help());
290-
return;
291-
}
292-
commands::ModelAliasCmd mdc;
293-
mdc.Exec(cml_data_.config.apiServerHost,
294-
std::stoi(cml_data_.config.apiServerPort), cml_data_.model_id,
295-
cml_data_.model_alias);
296-
});
297276
// Model update parameters comment
298277
ModelUpdate(models_cmd);
299278

@@ -384,6 +363,41 @@ void CommandLineParser::SetupEngineCommands() {
384363
EngineUninstall(uninstall_cmd, engine_name);
385364
}
386365

366+
auto engine_upd_cmd = engines_cmd->add_subcommand("update", "Update engine");
367+
engine_upd_cmd->usage("Usage:\n" + commands::GetCortexBinary() +
368+
" engines update [engine_name]");
369+
engine_upd_cmd->callback([this, engine_upd_cmd] {
370+
if (std::exchange(executed_, true))
371+
return;
372+
if (engine_upd_cmd->get_subcommands().empty()) {
373+
CLI_LOG("[engine_name] is required\n");
374+
CLI_LOG(engine_upd_cmd->help());
375+
}
376+
});
377+
engine_upd_cmd->group(kSubcommands);
378+
for (auto& engine : engine_service_.kSupportEngines) {
379+
std::string engine_name{engine};
380+
EngineUpdate(engine_upd_cmd, engine_name);
381+
}
382+
383+
auto engine_use_cmd =
384+
engines_cmd->add_subcommand("use", "Set engine as default");
385+
engine_use_cmd->usage("Usage:\n" + commands::GetCortexBinary() +
386+
" engines use [engine_name]");
387+
engine_use_cmd->callback([this, engine_use_cmd] {
388+
if (std::exchange(executed_, true))
389+
return;
390+
if (engine_use_cmd->get_subcommands().empty()) {
391+
CLI_LOG("[engine_name] is required\n");
392+
CLI_LOG(engine_use_cmd->help());
393+
}
394+
});
395+
engine_use_cmd->group(kSubcommands);
396+
for (auto& engine : engine_service_.kSupportEngines) {
397+
std::string engine_name{engine};
398+
EngineUse(engine_use_cmd, engine_name);
399+
}
400+
387401
EngineGet(engines_cmd);
388402
}
389403

@@ -400,7 +414,11 @@ void CommandLineParser::SetupSystemCommands() {
400414
<< " to " << cml_data_.port);
401415
auto config_path = file_manager_utils::GetConfigurationPath();
402416
cml_data_.config.apiServerPort = std::to_string(cml_data_.port);
403-
config_yaml_utils::DumpYamlConfig(cml_data_.config, config_path.string());
417+
auto result = config_yaml_utils::DumpYamlConfig(cml_data_.config,
418+
config_path.string());
419+
if (result.has_error()) {
420+
CLI_LOG("Error update " << config_path.string() << result.error());
421+
}
404422
}
405423
commands::ServerStartCmd ssc;
406424
ssc.Exec(cml_data_.config.apiServerHost,
@@ -417,8 +435,7 @@ void CommandLineParser::SetupSystemCommands() {
417435
ssc.Exec();
418436
});
419437

420-
auto ps_cmd =
421-
app_.add_subcommand("ps", "Show active model statuses");
438+
auto ps_cmd = app_.add_subcommand("ps", "Show active model statuses");
422439
ps_cmd->group(kSystemGroup);
423440
ps_cmd->usage("Usage:\n" + commands::GetCortexBinary() + "ps");
424441
ps_cmd->callback([&]() {
@@ -460,13 +477,16 @@ void CommandLineParser::EngineInstall(CLI::App* parent,
460477
install_engine_cmd->add_option("-s, --source", src,
461478
"Install engine by local path");
462479

480+
install_engine_cmd->add_flag("-m, --menu", cml_data_.show_menu,
481+
"Display menu for engine variant selection");
482+
463483
install_engine_cmd->callback([this, engine_name, &version, &src] {
464484
if (std::exchange(executed_, true))
465485
return;
466486
try {
467-
commands::EngineInstallCmd(download_service_,
468-
cml_data_.config.apiServerHost,
469-
std::stoi(cml_data_.config.apiServerPort))
487+
commands::EngineInstallCmd(
488+
download_service_, cml_data_.config.apiServerHost,
489+
std::stoi(cml_data_.config.apiServerPort), cml_data_.show_menu)
470490
.Exec(engine_name, version, src);
471491
} catch (const std::exception& e) {
472492
CTL_ERR(e.what());
@@ -494,6 +514,47 @@ void CommandLineParser::EngineUninstall(CLI::App* parent,
494514
});
495515
}
496516

517+
void CommandLineParser::EngineUpdate(CLI::App* parent,
518+
const std::string& engine_name) {
519+
auto engine_update_cmd = parent->add_subcommand(engine_name, "");
520+
engine_update_cmd->usage("Usage:\n" + commands::GetCortexBinary() +
521+
" engines update " + engine_name);
522+
engine_update_cmd->group(kEngineGroup);
523+
524+
engine_update_cmd->callback([this, engine_name] {
525+
if (std::exchange(executed_, true))
526+
return;
527+
try {
528+
commands::EngineUpdateCmd().Exec(
529+
cml_data_.config.apiServerHost,
530+
std::stoi(cml_data_.config.apiServerPort), engine_name);
531+
} catch (const std::exception& e) {
532+
CTL_ERR(e.what());
533+
}
534+
});
535+
}
536+
537+
void CommandLineParser::EngineUse(CLI::App* parent,
538+
const std::string& engine_name) {
539+
auto engine_use_cmd = parent->add_subcommand(engine_name, "");
540+
engine_use_cmd->usage("Usage:\n" + commands::GetCortexBinary() +
541+
" engines use " + engine_name);
542+
engine_use_cmd->group(kEngineGroup);
543+
544+
engine_use_cmd->callback([this, engine_name] {
545+
if (std::exchange(executed_, true))
546+
return;
547+
auto result = commands::EngineUseCmd().Exec(
548+
cml_data_.config.apiServerHost,
549+
std::stoi(cml_data_.config.apiServerPort), engine_name);
550+
if (result.has_error()) {
551+
CTL_ERR(result.error());
552+
} else {
553+
CTL_INF("Engine " << engine_name << " is set as default");
554+
}
555+
});
556+
}
557+
497558
void CommandLineParser::EngineGet(CLI::App* parent) {
498559
auto get_cmd = parent->add_subcommand("get", "Get engine info");
499560
get_cmd->usage("Usage:\n" + commands::GetCortexBinary() +

engine/cli/command_line_parser.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,12 @@ class CommandLineParser {
2727

2828
void EngineUninstall(CLI::App* parent, const std::string& engine_name);
2929

30+
void EngineUpdate(CLI::App* parent, const std::string& engine_name);
31+
3032
void EngineGet(CLI::App* parent);
33+
34+
void EngineUse(CLI::App* parent, const std::string& engine_name);
35+
3136
void ModelUpdate(CLI::App* parent);
3237

3338
CLI::App app_;
@@ -50,6 +55,7 @@ class CommandLineParser {
5055
bool display_engine = false;
5156
bool display_version = false;
5257
std::string filter = "";
58+
bool show_menu = false;
5359

5460
int port;
5561
config_yaml_utils::CortexConfig config;

engine/cli/commands/chat_completion_cmd.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ struct ChunkParser {
2929
is_done = true;
3030
} else {
3131
try {
32-
content = nlohmann::json::parse(s)["choices"][0]["delta"]["content"];
33-
} catch (const nlohmann::json::parse_error& e) {
32+
content =
33+
json_helper::ParseJsonString(s)["choices"][0]["delta"]["content"]
34+
.asString();
35+
} catch (const std::exception& e) {
3436
CTL_WRN("JSON parse error: " << e.what());
3537
}
3638
}

0 commit comments

Comments
 (0)