Skip to content
This repository was archived by the owner on Jul 4, 2025. It is now read-only.
Merged
3 changes: 2 additions & 1 deletion engine/cli/commands/ps_cmd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ void PsCmd::Exec(const std::string& host, int port) {
for (const auto& item : res.value()["data"]) {
ModelLoadedStatus model_status;
// TODO(sang) hardcode for now
model_status.engine = kLlamaEngine;
model_status.engine = item["engine"].isNull()
? kLlamaEngine : item["engine"].asString();
model_status.model = item["id"].asString();
model_status.ram = item["ram"].asUInt64();
model_status.start_time = item["start_time"].asUInt64();
Expand Down
27 changes: 27 additions & 0 deletions engine/controllers/models.cc
Original file line number Diff line number Diff line change
Expand Up @@ -854,4 +854,31 @@ void Models::GetModelSource(
resp->setStatusCode(k200OK);
callback(resp);
}
}

void Models::GetRepositoryList(
const HttpRequestPtr& req,
std::function<void(const HttpResponsePtr&)>&& callback,
std::optional<std::string> author) {
if (!author.has_value())
author = "cortexso";
auto res = model_src_svc_->GetRepositoryList(author.value());
if (res.has_error()) {
Json::Value ret;
ret["message"] = res.error();
auto resp = cortex_utils::CreateCortexHttpJsonResponse(ret);
resp->setStatusCode(k400BadRequest);
callback(resp);
} else {
auto& info = res.value();
Json::Value ret;
Json::Value arr(Json::arrayValue);
for (auto const& i : info) {
arr.append(i);
}
ret["data"] = arr;
auto resp = cortex_utils::CreateCortexHttpJsonResponse(ret);
resp->setStatusCode(k200OK);
callback(resp);
}
}
6 changes: 6 additions & 0 deletions engine/controllers/models.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class Models : public drogon::HttpController<Models, false> {
ADD_METHOD_TO(Models::DeleteModelSource, "/v1/models/sources", Delete);
ADD_METHOD_TO(Models::GetModelSources, "/v1/models/sources", Get);
ADD_METHOD_TO(Models::GetModelSource, "/v1/models/sources/{src}", Get);
ADD_METHOD_TO(Models::GetRepositoryList, "/v1/models/hub?author={author}",
Get);
METHOD_LIST_END

explicit Models(std::shared_ptr<DatabaseService> db_service,
Expand Down Expand Up @@ -111,6 +113,10 @@ class Models : public drogon::HttpController<Models, false> {
std::function<void(const HttpResponsePtr&)>&& callback,
const std::string& src);

void GetRepositoryList(const HttpRequestPtr& req,
std::function<void(const HttpResponsePtr&)>&& callback,
std::optional<std::string> author);

private:
std::shared_ptr<DatabaseService> db_service_;
std::shared_ptr<ModelService> model_service_;
Expand Down
21 changes: 20 additions & 1 deletion engine/repositories/file_fs_repository.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,21 @@ std::filesystem::path FileFsRepository::GetFilePath() const {
return data_folder_path_ / kFileContainerFolderName;
}

std::filesystem::path SanitizePath(const std::filesystem::path & user_input,
const std::filesystem::path & basedir) {

auto abs_base = std::filesystem::canonical(basedir);
std::filesystem::path resolved_path = std::filesystem::weakly_canonical(
std::filesystem::path(basedir) / std::filesystem::path(user_input));
/* Ensure the resolved path is within our basedir */
for (auto p = resolved_path; !p.empty(); p = p.parent_path()) {
if (std::filesystem::equivalent(p, abs_base)) {
return resolved_path;
}
}
return {};
}

cpp::result<void, std::string> FileFsRepository::StoreFile(
OpenAi::File& file_metadata, const char* content, uint64_t length) {
auto file_container_path = GetFilePath();
Expand All @@ -18,7 +33,11 @@ cpp::result<void, std::string> FileFsRepository::StoreFile(
}

auto original_filename = file_metadata.filename;
auto file_full_path = file_container_path / original_filename;
auto file_full_path = SanitizePath(original_filename, file_container_path);

if (file_full_path.empty()) {
return cpp::fail("Error resolving path in: " + original_filename);
}

// Handle duplicate filenames
int counter = 1;
Expand Down
36 changes: 36 additions & 0 deletions engine/services/database_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,125 +6,161 @@ std::optional<EngineEntry> DatabaseService::UpsertEngine(
const std::string& api_key, const std::string& url,
const std::string& version, const std::string& variant,
const std::string& status, const std::string& metadata) {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Engines().UpsertEngine(engine_name, type, api_key, url,
version, variant, status, metadata);
}

std::optional<std::vector<EngineEntry>> DatabaseService::GetEngines() const {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Engines().GetEngines();
}

std::optional<EngineEntry> DatabaseService::GetEngineById(int id) const {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Engines().GetEngineById(id);
}

std::optional<EngineEntry> DatabaseService::GetEngineByNameAndVariant(
const std::string& engine_name,
const std::optional<std::string> variant) const {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Engines().GetEngineByNameAndVariant(engine_name, variant);
}

std::optional<std::string> DatabaseService::DeleteEngineById(int id) {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Engines().DeleteEngineById(id);
}
// end engines

// begin file
cpp::result<std::vector<OpenAi::File>, std::string>
DatabaseService::GetFileList() const {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::File().GetFileList();
}

cpp::result<OpenAi::File, std::string> DatabaseService::GetFileById(
const std::string& file_id) const {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::File().GetFileById(file_id);
}

cpp::result<void, std::string> DatabaseService::AddFileEntry(
OpenAi::File& file) {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::File().AddFileEntry(file);
}

cpp::result<void, std::string> DatabaseService::DeleteFileEntry(
const std::string& file_id) {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::File().DeleteFileEntry(file_id);
}
// end file

// begin hardware
cpp::result<std::vector<HardwareEntry>, std::string>
DatabaseService::LoadHardwareList() const {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Hardware().LoadHardwareList();
}

cpp::result<bool, std::string> DatabaseService::AddHardwareEntry(
const HardwareEntry& new_entry) {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Hardware().AddHardwareEntry(new_entry);
}

bool DatabaseService::HasHardwareEntry(const std::string& id) {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Hardware().HasHardwareEntry(id);
}

cpp::result<bool, std::string> DatabaseService::UpdateHardwareEntry(
const std::string& id, const HardwareEntry& updated_entry) {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Hardware().UpdateHardwareEntry(id, updated_entry);
}

cpp::result<bool, std::string> DatabaseService::DeleteHardwareEntry(
const std::string& id) {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Hardware().DeleteHardwareEntry(id);
}

cpp::result<bool, std::string> DatabaseService::UpdateHardwareEntry(
const std::string& id, int hw_id, int sw_id) const {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Hardware().UpdateHardwareEntry(id, hw_id, sw_id);
}
// end hardware

// begin models
cpp::result<std::vector<ModelEntry>, std::string>
DatabaseService::LoadModelList() const {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Models().LoadModelList();
}

cpp::result<ModelEntry, std::string> DatabaseService::GetModelInfo(
const std::string& identifier) const {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Models().GetModelInfo(identifier);
}

cpp::result<bool, std::string> DatabaseService::AddModelEntry(
ModelEntry new_entry) {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Models().AddModelEntry(new_entry);
}

cpp::result<bool, std::string> DatabaseService::UpdateModelEntry(
const std::string& identifier, const ModelEntry& updated_entry) {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Models().UpdateModelEntry(identifier, updated_entry);
}

cpp::result<bool, std::string> DatabaseService::DeleteModelEntry(
const std::string& identifier) {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Models().DeleteModelEntry(identifier);
}

cpp::result<bool, std::string> DatabaseService::DeleteModelEntryWithOrg(
const std::string& src) {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Models().DeleteModelEntryWithOrg(src);
}

cpp::result<bool, std::string> DatabaseService::DeleteModelEntryWithRepo(
const std::string& src) {

std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Models().DeleteModelEntryWithRepo(src);
}

cpp::result<std::vector<std::string>, std::string>
DatabaseService::FindRelatedModel(const std::string& identifier) const {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Models().FindRelatedModel(identifier);
}

bool DatabaseService::HasModel(const std::string& identifier) const {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Models().HasModel(identifier);
}

cpp::result<std::vector<ModelEntry>, std::string> DatabaseService::GetModels(
const std::string& model_src) const {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Models().GetModels(model_src);
}

cpp::result<std::vector<ModelEntry>, std::string>
DatabaseService::GetModelSources() const {
std::lock_guard<std::mutex> l(mtx_);
return cortex::db::Models().GetModelSources();
}
// end models
9 changes: 7 additions & 2 deletions engine/services/database_service.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#include <mutex>
#include "database/engines.h"
#include "database/file.h"
#include "database/hardware.h"
Expand Down Expand Up @@ -39,9 +40,13 @@ class DatabaseService {
cpp::result<std::vector<HardwareEntry>, std::string> LoadHardwareList() const;
cpp::result<bool, std::string> AddHardwareEntry(
const HardwareEntry& new_entry);
bool HasHardwareEntry(const std::string& id);
cpp::result<bool, std::string> UpdateHardwareEntry(
const std::string& id, const HardwareEntry& updated_entry);
cpp::result<bool, std::string> DeleteHardwareEntry(const std::string& id);
cpp::result<bool, std::string> UpdateHardwareEntry(const std::string& id,
int hw_id,
int sw_id) const;

// models
cpp::result<std::vector<ModelEntry>, std::string> LoadModelList() const;
Expand All @@ -62,8 +67,8 @@ class DatabaseService {
bool HasModel(const std::string& identifier) const;
cpp::result<std::vector<ModelEntry>, std::string> GetModels(
const std::string& model_src) const;
cpp::result<std::vector<ModelEntry>, std::string> GetModelSources()
const;
cpp::result<std::vector<ModelEntry>, std::string> GetModelSources() const;

private:
mutable std::mutex mtx_;
};
13 changes: 6 additions & 7 deletions engine/services/hardware_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,7 @@ void HardwareService::UpdateHardwareInfos() {
using HwEntry = cortex::db::HardwareEntry;
CheckDependencies();
auto gpus = cortex::hw::GetGPUInfo();
cortex::db::Hardware hw_db;
auto b = hw_db.LoadHardwareList();
auto b = db_service_->LoadHardwareList();
// delete if not exists
auto exists = [&gpus](const std::string& uuid) {
for (auto const& g : gpus) {
Expand All @@ -308,12 +307,12 @@ void HardwareService::UpdateHardwareInfos() {
};
for (auto const& he : b.value()) {
if (!exists(he.uuid)) {
hw_db.DeleteHardwareEntry(he.uuid);
db_service_->DeleteHardwareEntry(he.uuid);
}
}

// Get updated list
b = hw_db.LoadHardwareList();
b = db_service_->LoadHardwareList();
std::vector<std::pair<int, int>> activated_gpu_bf;
std::string debug_b;
for (auto const& he : b.value()) {
Expand All @@ -326,15 +325,15 @@ void HardwareService::UpdateHardwareInfos() {
for (auto const& gpu : gpus) {
// ignore error
// Note: only support NVIDIA for now, so hardware_id = software_id
if (hw_db.HasHardwareEntry(gpu.uuid)) {
auto res = hw_db.UpdateHardwareEntry(gpu.uuid, std::stoi(gpu.id),
if (db_service_->HasHardwareEntry(gpu.uuid)) {
auto res = db_service_->UpdateHardwareEntry(gpu.uuid, std::stoi(gpu.id),
std::stoi(gpu.id));
if (res.has_error()) {
CTL_WRN(res.error());
}
} else {
auto res =
hw_db.AddHardwareEntry(HwEntry{.uuid = gpu.uuid,
db_service_->AddHardwareEntry(HwEntry{.uuid = gpu.uuid,
.type = "gpu",
.hardware_id = std::stoi(gpu.id),
.software_id = std::stoi(gpu.id),
Expand Down
9 changes: 4 additions & 5 deletions engine/services/model_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -858,8 +858,7 @@ cpp::result<StartModelResult, std::string> ModelService::StartModel(
} else {
// only report to user the error
for (auto& depend : depends) {

StopModel(depend);
(void)StopModel(depend);
}
}
CTL_ERR("Model failed to start with status code: " << status);
Expand All @@ -869,7 +868,7 @@ cpp::result<StartModelResult, std::string> ModelService::StartModel(

// Running remote model
if (engine_svc_->IsRemoteEngine(mc.engine)) {
engine_svc_->LoadEngine(mc.engine);
(void)engine_svc_->LoadEngine(mc.engine);
config::RemoteModelConfig remote_mc;
remote_mc.LoadFromYamlFile(
fmu::ToAbsoluteCortexDataPath(
Expand Down Expand Up @@ -1035,7 +1034,7 @@ cpp::result<bool, std::string> ModelService::StopModel(
// Stop all depends model
auto depends = python_model_config.depends;
for (auto& depend : depends) {
StopModel(depend);
(void)StopModel(depend);
}
}

Expand Down Expand Up @@ -1233,7 +1232,7 @@ cpp::result<std::optional<std::string>, std::string>
ModelService::MayFallbackToCpu(const std::string& model_path, int ngl,
int ctx_len, int n_batch, int n_ubatch,
const std::string& kv_cache_type) {
// TODO(sang) temporary disable this function
// TODO(sang) temporary disable this function
return std::nullopt;
assert(hw_service_);
auto hw_info = hw_service_->GetHardwareInfo();
Expand Down
Loading
Loading