Refactor project structure
This commit is contained in:
666
modules/ANSLLM/ANSLLM.cpp
Normal file
666
modules/ANSLLM/ANSLLM.cpp
Normal file
@@ -0,0 +1,666 @@
|
||||
#include "ANSLLM.h"
|
||||
#include <CkGlobal.h>
|
||||
#include <CkBinData.h>
|
||||
#include <CkByteData.h>
|
||||
#include <CkStringTable.h>
|
||||
#include <CkStringBuilder.h>
|
||||
#include <CkJsonObject.h>
|
||||
|
||||
static bool ansllmLicenceValid = false;
|
||||
static std::once_flag ansllmLicenseOnceFlag;
|
||||
|
||||
namespace ANSCENTER
|
||||
{
|
||||
static void VerifyGlobalANSLMLicense(const std::string& licenseKey) {
|
||||
try {
|
||||
static const std::vector<std::pair<int, std::string>> licenseChecks = {
|
||||
{1000, "ANNHUB-LV"},
|
||||
{1001, "DLHUB-LV"},
|
||||
{1002, "ODHUB-LV"},
|
||||
{1003, "ANSVIS"},
|
||||
{1004, "ANSFR"},
|
||||
{1005, "ANSOCR"},
|
||||
{1006, "ANSALPR"},
|
||||
{1007, "ANSCV"},
|
||||
{1008, "ANSSRT"}
|
||||
};
|
||||
ansllmLicenceValid = false;
|
||||
for (const auto& [productId, productName] : licenseChecks) {
|
||||
if (ANSCENTER::ANSLicenseHelper::LicenseVerification(licenseKey, productId, productName)) {
|
||||
ansllmLicenceValid = true;
|
||||
break; // Stop at the first valid license
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
ansllmLicenceValid = false;
|
||||
}
|
||||
}
|
||||
ANSLLM::ANSLLM() {
|
||||
_unlockCode = "ANSDRC.CB1122026_MEQCIFwO1IFQCG0BhZwsXFO68QUU6mDB5uge4duOsqOJanEyAiAB67ahqnXin4SRy0vIegISgbFlpldmbuS5gbU21GYVqA==";// "ANSDRC.CB1082025_Ax6P3M7F8B3d";//
|
||||
}
|
||||
ANSLLM::~ANSLLM() noexcept = default;
|
||||
|
||||
void ANSLLM::CheckLicense() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
// Check once globally
|
||||
std::call_once(ansllmLicenseOnceFlag, [this]() {
|
||||
VerifyGlobalANSLMLicense(_licenseKey);
|
||||
});
|
||||
// Update this instance's local license flag
|
||||
_isLicenseValid = ansllmLicenceValid;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
this->_logger.LogFatal("ANSLLM::CheckLicense. Error:", e.what(), __FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
void ANSLLM::CheckUnlockCode() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
CkGlobal glob;
|
||||
_unlockCode = "ANSDRC.CB1122026_MEQCIFwO1IFQCG0BhZwsXFO68QUU6mDB5uge4duOsqOJanEyAiAB67ahqnXin4SRy0vIegISgbFlpldmbuS5gbU21GYVqA==";// "ANSDRC.CB1082025_Ax6P3M7F8B3d";
|
||||
_isUnlockCodeValid = glob.UnlockBundle(_unlockCode.c_str());
|
||||
|
||||
if (!_isUnlockCodeValid) {
|
||||
_logger.LogFatal("ANSLLM::CheckUnlockCode", glob.lastErrorText(), __FILE__, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
int status = glob.get_UnlockStatus();
|
||||
if (status != 2) {
|
||||
_logger.LogDebug("ANSLLM::CheckUnlockCode", "Unlocked in trial mode.", __FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::CheckUnlockCode", e.what(), __FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
bool ANSLLM::Initialize(const std::string& licenseKey, bool localLLM) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
_licenseKey = licenseKey;
|
||||
_localLLM = localLLM;
|
||||
CheckLicense();
|
||||
CheckUnlockCode();
|
||||
|
||||
if (_localLLM) {
|
||||
// Auto-configure for local Ollama: use custom provider with ChatCompletions API spec
|
||||
// Must use "custom" — setting "openai" resets BaseUrl to api.openai.com
|
||||
ai.put_Provider("custom");
|
||||
ai.put_ApiSpec("ChatCompletions");
|
||||
ai.put_BaseUrl(_ollamaBaseUrl.c_str());
|
||||
ai.put_ApiKey("ollama"); // Ollama doesn't require a real API key
|
||||
_logger.LogDebug("ANSLLM::Initialize", "Configured for local Ollama at " + _ollamaBaseUrl, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
return _isLicenseValid && _isUnlockCodeValid;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::Initialize", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool ANSLLM::SetLLMProvider(const std::string& llmProvider) {
|
||||
if (llmProvider.empty()) return false;
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
ai.put_Provider(llmProvider.c_str());
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::SetLLMProvider", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
std::string ANSLLM::GetLLMProvider() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
CkString str;
|
||||
ai.get_Provider(str);
|
||||
const char* cstr = str.getString();
|
||||
return (cstr != nullptr) ? std::string(cstr) : std::string();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::GetLLMProvider", e.what(), __FILE__, __LINE__);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
bool ANSLLM::SetApiKey(const std::string& apiKey) {
|
||||
if (apiKey.empty()) return false;
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
ai.put_ApiKey(apiKey.c_str());
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::SetApiKey", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::vector<std::string> ANSLLM::GetModelList() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
std::vector<std::string> modelList;
|
||||
|
||||
try {
|
||||
CkStringTable st;
|
||||
|
||||
if (!ai.GetModels(st)) {
|
||||
const char* errText = ai.lastErrorText();
|
||||
const std::string errorMsg = (errText != nullptr) ? errText : "Unknown error";
|
||||
_logger.LogError("ANSLLM::GetModelList",
|
||||
"Failed to get models: " + errorMsg,
|
||||
__FILE__, __LINE__);
|
||||
return modelList;
|
||||
}
|
||||
|
||||
const int count = st.get_Count();
|
||||
|
||||
if (count <= 0) {
|
||||
return modelList;
|
||||
}
|
||||
|
||||
modelList.reserve(static_cast<size_t>(count));
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
const char* modelName = st.stringAt(i);
|
||||
if (modelName != nullptr && modelName[0] != '\0') {
|
||||
modelList.emplace_back(modelName);
|
||||
}
|
||||
}
|
||||
|
||||
return modelList;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::GetModelList",
|
||||
std::string("Exception: ") + e.what(),
|
||||
__FILE__, __LINE__);
|
||||
return modelList;
|
||||
}
|
||||
catch (...) {
|
||||
_logger.LogFatal("ANSLLM::GetModelList",
|
||||
"Unknown exception occurred",
|
||||
__FILE__, __LINE__);
|
||||
return modelList;
|
||||
}
|
||||
}
|
||||
|
||||
bool ANSLLM::SetModel(const std::string& modelName) {
|
||||
if (modelName.empty()) return false;
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
ai.put_Model(modelName.c_str());
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::SetModel", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool ANSLLM::SetTranscriptMode(bool transcriptMode) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
ai.put_FullTranscript(transcriptMode);
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::SetTranscriptMode", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ANSLLM::InputAddText(const std::string& inputText) {
|
||||
if (inputText.empty()) return false;
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
ai.InputAddText(inputText.c_str());
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::InputAddText", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string ANSLLM::Ask(const std::string& prompt) {
|
||||
if (prompt.empty()) return "";
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
// Ask the AI for text output.
|
||||
bool success = ai.Ask(prompt.c_str());
|
||||
if (success == false) {
|
||||
const char* errText = ai.lastErrorText();
|
||||
return (errText != nullptr) ? std::string(errText) : std::string("Unknown error");
|
||||
}
|
||||
|
||||
// Get the text response.
|
||||
CkStringBuilder sbResponse;
|
||||
ai.GetOutputTextSb(sbResponse);
|
||||
const char* cstr = sbResponse.getAsString();
|
||||
return (cstr != nullptr) ? std::string(cstr) : std::string();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::Ask", e.what(), __FILE__, __LINE__);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
bool ANSLLM::CreateConversation(const std::string& systemMessage, const std::string& developerMessage, const std::string& conversationName) {
|
||||
|
||||
if (systemMessage.empty() || developerMessage.empty() || conversationName.empty()) {
|
||||
return false;
|
||||
}
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
return ai.NewConvo(conversationName.c_str(), systemMessage.c_str(), developerMessage.c_str());
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::CreateConversation", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ANSLLM::SetConversation(const std::string& conversationName) {
|
||||
|
||||
if (conversationName.empty()) return false;
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
|
||||
ai.put_SelectedConvo(conversationName.c_str());
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::SetConversation", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ANSLLM::InputAddImageUrl(const std::string& imageURL, const std::string& summary) {
|
||||
if (imageURL.empty()) return false;
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
return ai.InputAddImageUrl(imageURL.c_str(), summary.c_str());
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::InputAddImageUrl", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ANSLLM::InputAddImageFromPath(const std::string& filePath, const char* summary) {
|
||||
|
||||
if (filePath.empty()) return false;
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
CkBinData bd;
|
||||
bool success = bd.LoadFile(filePath.c_str());
|
||||
if (!success) {
|
||||
const char* errText = bd.lastErrorText();
|
||||
_logger.LogError("ANSLLM::InputAddImageFromPath",
|
||||
(errText != nullptr) ? errText : "Failed to load file",
|
||||
__FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
return ai.InputAddImageData(bd, summary);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::InputAddImageFromPath", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool ANSLLM::InputAddImageFromBase64(const std::string& jpegBase64String, const char* summary) {
|
||||
if (jpegBase64String.empty()) return false;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
CkBinData bd;
|
||||
|
||||
// Load base64 encoded JPEG data into CkBinData
|
||||
bool success = bd.AppendEncoded(jpegBase64String.c_str(), "base64");
|
||||
if (!success) {
|
||||
_logger.LogError("ANSLLM::InputAddImage",
|
||||
bd.lastErrorText(),
|
||||
__FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
return ai.InputAddImageData(bd, summary);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::InputAddImage", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ANSLLM::InputAddFileData(const std::string& filePath, const char* summary) {
|
||||
if (filePath.empty()) return false;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
CkBinData bd;
|
||||
bool success = bd.LoadFile(filePath.c_str());
|
||||
if (!success) {
|
||||
const char* errText = bd.lastErrorText();
|
||||
_logger.LogError("ANSLLM::InputAddFileData",
|
||||
(errText != nullptr) ? errText : "Failed to load file",
|
||||
__FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
return ai.InputAddImageData(bd, summary);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::InputAddFileData", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool ANSLLM::InputAddFileURL(const std::string& fileURL, const char* summary) {
|
||||
if (fileURL.empty()) return false;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
|
||||
return ai.InputAddFileUrl(fileURL.c_str(), summary);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::InputAddFileURL", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Extra methods
|
||||
bool ANSLLM::ClearInputs() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
ai.InputClear();
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::ClearInputs", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
std::vector<std::string> ANSLLM::GetConversationList() {
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
std::vector<std::string> convList;
|
||||
try {
|
||||
CkStringTable st;
|
||||
|
||||
if (!ai.ListConvos(st)) {
|
||||
const char* errText = ai.lastErrorText();
|
||||
const std::string errorMsg = (errText != nullptr) ? errText : "Unknown error";
|
||||
_logger.LogError("ANSLLM::GetConversationList",
|
||||
"Failed to get conversations: " + errorMsg,
|
||||
__FILE__, __LINE__);
|
||||
return convList;
|
||||
}
|
||||
|
||||
const int count = st.get_Count();
|
||||
|
||||
if (count <= 0) {
|
||||
return convList;
|
||||
}
|
||||
|
||||
convList.reserve(static_cast<size_t>(count));
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
const char* convName = st.stringAt(i);
|
||||
if (convName != nullptr && convName[0] != '\0') {
|
||||
convList.emplace_back(convName);
|
||||
}
|
||||
}
|
||||
return convList;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::GetConversationList", e.what(), __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
bool ANSLLM::DeleteConversation(const std::string& conversationName) {
|
||||
|
||||
if (conversationName.empty()) return false;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
return ai.DeleteConvo(conversationName.c_str());
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::DeleteConversation", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool ANSLLM::SetUTF8(bool b) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
ai.put_Utf8(b);
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::SetUTF8", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ANSLLM::GetUTF8() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
return ai.get_Utf8();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::GetUTF8", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int ANSLLM::PollAi(bool abort) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
return ai.PollAi(abort);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::PollAi", e.what(), __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
bool ANSLLM::SetLocalLLM(bool localLLM) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
_localLLM = localLLM;
|
||||
if (_localLLM) {
|
||||
ai.put_Provider("custom");
|
||||
ai.put_ApiSpec("ChatCompletions");
|
||||
ai.put_BaseUrl(_ollamaBaseUrl.c_str());
|
||||
ai.put_ApiKey("ollama");
|
||||
_logger.LogDebug("ANSLLM::SetLocalLLM", "Configured for local Ollama at " + _ollamaBaseUrl, __FILE__, __LINE__);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::SetLocalLLM", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool ANSLLM::SetOllamaBaseUrl(const std::string& baseUrl) {
|
||||
if (baseUrl.empty()) return false;
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
_ollamaBaseUrl = baseUrl;
|
||||
if (_localLLM) {
|
||||
ai.put_BaseUrl(_ollamaBaseUrl.c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::SetOllamaBaseUrl", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool ANSLLM::SetBaseURL(const std::string& baseURL) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
ai.put_BaseUrl(baseURL.c_str());
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::SetBaseURL", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
int ANSLLM::GetHeartbeatMs() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
return ai.get_HeartbeatMs();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::GetHeartbeatMs", e.what(), __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
bool ANSLLM::SetHeartbeatMs(int heartbeatMs) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
ai.put_HeartbeatMs(heartbeatMs);
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::SetHeartbeatMs", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool ANSLLM::GetHostedConversation() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
return ai.get_HostedConvo();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::GetHostedConversation", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
bool ANSLLM::SetHostedConversation(bool hostedConversation) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
ai.put_HostedConvo(hostedConversation);
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::SetHostedConversation", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ANSLLM::GetStreamingMode() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
return ai.get_Streaming();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::GetStreamingMode", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
bool ANSLLM::SetStreamingMode(bool streamingMode) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
ai.put_Streaming(streamingMode);
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::SetStreamingMode", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int ANSLLM::GetIdleTimeoutMs() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
return ai.get_IdleTimeoutMs();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::GetIdleTimeoutMs", e.what(), __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
bool ANSLLM::SetIdleTimeoutMs(int idleTimeoutMs) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
ai.put_IdleTimeoutMs(idleTimeoutMs);
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::SetIdleTimeoutMs", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string ANSLLM::GetLastErrorMessage() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
const char* errorText = ai.lastErrorText();
|
||||
return (errorText != nullptr) ? std::string(errorText) : std::string();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::GetLastErrorMessage", e.what(), __FILE__, __LINE__);
|
||||
return e.what();
|
||||
}
|
||||
}
|
||||
std::string ANSLLM::GetOutputText() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
CkString str;
|
||||
ai.GetOutputText(str);
|
||||
const char* cstr = str.getString();
|
||||
return (cstr != nullptr) ? std::string(cstr) : std::string();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::GetOutputText", e.what(), __FILE__, __LINE__);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
std::string ANSLLM::GetOutputTextSb() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
CkStringBuilder sb;
|
||||
ai.GetOutputTextSb(sb);
|
||||
const char* cstr = sb.getAsString();
|
||||
return (cstr != nullptr) ? std::string(cstr) : std::string();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::GetOutputTextSb", e.what(), __FILE__, __LINE__);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
bool ANSLLM::SetSleepMs(int sleepMs) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
ai.SleepMs(sleepMs);
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::SetSleepMs", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ANSLLM::SetAskParams(double temperature) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
CkJsonObject obj;
|
||||
std::string strTemp = std::to_string(temperature);
|
||||
obj.UpdateString("temperature", strTemp.c_str());
|
||||
ai.SetAskParams(obj);
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSLLM::SetAskParams", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
146
modules/ANSLLM/ANSLLM.h
Normal file
146
modules/ANSLLM/ANSLLM.h
Normal file
@@ -0,0 +1,146 @@
|
||||
#ifndef ANSLLM_H
|
||||
#define ANSLLM_H
|
||||
#define ANSLLM_API __declspec(dllexport)
|
||||
#pragma once
|
||||
#include "LabVIEWHeader/extcode.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "ANSLicense.h"
|
||||
#include <CkAi.h>
|
||||
//#include <CkRest.h>
|
||||
//#include "CkAuthGoogle.h"
|
||||
//#include "CkByteData.h"
|
||||
//#include <CkAuthAws.h>
|
||||
//#include <CkXml.h>
|
||||
//#include <CkCrypt2.h>
|
||||
//#include <CkSocket.h>
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
namespace ANSCENTER {
|
||||
class ANSLLM_API ANSLLM {
|
||||
private:
|
||||
// Protects all shared mutable data
|
||||
mutable std::recursive_mutex _mutex;
|
||||
bool _isUnlockCodeValid{ false };
|
||||
bool _isLicenseValid{ false };
|
||||
bool _localLLM{ false };
|
||||
std::string _licenseKey;
|
||||
std::string _unlockCode;
|
||||
std::string _ollamaBaseUrl{ "http://localhost:11434/v1" };
|
||||
SPDLogger& _logger = SPDLogger::GetInstance("ANSLLM", false);
|
||||
CkAi ai;
|
||||
|
||||
public:
|
||||
ANSLLM();
|
||||
~ANSLLM() noexcept;
|
||||
[[nodiscard]] bool Initialize(const std::string& licenseKey, bool localLLM = false);
|
||||
void CheckLicense();
|
||||
void CheckUnlockCode();
|
||||
|
||||
bool SetLLMProvider(const std::string& llmProvider);
|
||||
[[nodiscard]] std::string GetLLMProvider();
|
||||
bool SetApiKey(const std::string& apiKey);
|
||||
[[nodiscard]] std::vector<std::string> GetModelList();
|
||||
bool SetTranscriptMode(bool transcriptMode);
|
||||
bool SetModel(const std::string& modelName);
|
||||
|
||||
bool InputAddText(const std::string& inputText);
|
||||
bool InputAddImageUrl(const std::string& imageURL, const std::string& summary);
|
||||
bool InputAddImageFromPath(const std::string& filePath, const char* summary);
|
||||
bool InputAddImageFromBase64(const std::string& base64Image, const char* summary);
|
||||
|
||||
bool InputAddFileURL(const std::string& fileURL, const char* summary);
|
||||
bool InputAddFileData(const std::string& filePath, const char* summary);
|
||||
bool ClearInputs();
|
||||
[[nodiscard]] std::vector<std::string> GetConversationList();
|
||||
|
||||
bool CreateConversation(const std::string& systemMessage, const std::string& developerMessage, const std::string& conversationName);
|
||||
bool SetConversation(const std::string& conversationName);
|
||||
bool DeleteConversation(const std::string& conversationName);
|
||||
[[nodiscard]] std::string Ask(const std::string& prompt);
|
||||
|
||||
|
||||
// Other methods and members
|
||||
bool SetUTF8(bool b);
|
||||
[[nodiscard]] bool GetUTF8();
|
||||
|
||||
// PollAi
|
||||
[[nodiscard]] int PollAi(bool abort);
|
||||
|
||||
// Local LLM methods
|
||||
bool SetLocalLLM(bool localLLM);
|
||||
bool SetOllamaBaseUrl(const std::string& baseUrl);
|
||||
bool SetBaseURL(const std::string& baseURL);
|
||||
[[nodiscard]] int GetHeartbeatMs();
|
||||
bool SetHeartbeatMs(int heartbeatMs);
|
||||
|
||||
[[nodiscard]] bool GetHostedConversation();
|
||||
bool SetHostedConversation(bool hostedConversation);
|
||||
|
||||
[[nodiscard]] bool GetStreamingMode();
|
||||
bool SetStreamingMode(bool streamingMode);
|
||||
|
||||
[[nodiscard]] int GetIdleTimeoutMs();
|
||||
bool SetIdleTimeoutMs(int idleTimeoutMs);
|
||||
|
||||
bool SetSleepMs(int sleepMs);
|
||||
[[nodiscard]] std::string GetLastErrorMessage();
|
||||
|
||||
// Parameters methods
|
||||
[[nodiscard]] std::string GetOutputText();
|
||||
[[nodiscard]] std::string GetOutputTextSb();
|
||||
|
||||
bool SetAskParams(double temperature);
|
||||
//bool SetProviderParams(std::string providerParams);
|
||||
};
|
||||
}
|
||||
|
||||
extern "C" ANSLLM_API int CreateANSLLMHandle(ANSCENTER::ANSLLM** Handle, const char* licenseKey, int localLLM = 0);
|
||||
extern "C" ANSLLM_API int ReleaseANSLLMHandle(ANSCENTER::ANSLLM** Handle);
|
||||
|
||||
extern "C" ANSLLM_API int SetANSLLMProvider(ANSCENTER::ANSLLM** Handle, const char* provider);
|
||||
extern "C" ANSLLM_API int GetANSLLMProvider(ANSCENTER::ANSLLM** Handle, LStrHandle provider);
|
||||
|
||||
extern "C" ANSLLM_API int SetApiKey(ANSCENTER::ANSLLM** Handle, const char* apiKey);
|
||||
extern "C" ANSLLM_API int ANSLLMGetModelList(ANSCENTER::ANSLLM** Handle, LStrHandle modelList);
|
||||
extern "C" ANSLLM_API int ANSLLMSetTranscriptMode(ANSCENTER::ANSLLM** Handle, int transcriptMode);
|
||||
extern "C" ANSLLM_API int ANSLLMSetModel(ANSCENTER::ANSLLM** Handle, const char* modelName);
|
||||
|
||||
extern "C" ANSLLM_API int ANSLLMInputAddText(ANSCENTER::ANSLLM** Handle, const char* inputText);
|
||||
extern "C" ANSLLM_API int ANSLLMInputAddImageUrl(ANSCENTER::ANSLLM** Handle, const char* imageURL, const char* summary);
|
||||
extern "C" ANSLLM_API int ANSLLMInputAddImageFromPath(ANSCENTER::ANSLLM** Handle, const char* filePath, const char* summary);
|
||||
extern "C" ANSLLM_API int ANSLLMInputAddImageFromBase64(ANSCENTER::ANSLLM** Handle, const char* base64Image, const char* summary);
|
||||
extern "C" ANSLLM_API int ANSLLMInputAddFileURL(ANSCENTER::ANSLLM** Handle, const char* fileURL, const char* summary);
|
||||
extern "C" ANSLLM_API int ANSLLMInputAddFileData(ANSCENTER::ANSLLM** Handle, const char* filePath, const char* summary);
|
||||
extern "C" ANSLLM_API int ANSLLMCreateConversation(ANSCENTER::ANSLLM** Handle, const char* systemMessage, const char* developerMessage, const char* conversationName);
|
||||
extern "C" ANSLLM_API int ANSLLMSetConversation(ANSCENTER::ANSLLM** Handle, const char* conversationName);
|
||||
extern "C" ANSLLM_API int ANSLLMAsk(ANSCENTER::ANSLLM** Handle, const char* prompt, LStrHandle response);
|
||||
|
||||
extern "C" ANSLLM_API int ANSLLMClearInput(ANSCENTER::ANSLLM** Handle);
|
||||
extern "C" ANSLLM_API int ANSLLMGetConversationList(ANSCENTER::ANSLLM** Handle, LStrHandle conversationList);
|
||||
extern "C" ANSLLM_API int ANSLLMDeleteConversation(ANSCENTER::ANSLLM** Handle, const char* conversationName);
|
||||
extern "C" ANSLLM_API int ANSLLMSetUTF8(ANSCENTER::ANSLLM** Handle, int utf8Mode);
|
||||
extern "C" ANSLLM_API int ANSLLMGetUTF8(ANSCENTER::ANSLLM** Handle);
|
||||
extern "C" ANSLLM_API int ANSLLMPollAi(ANSCENTER::ANSLLM** Handle, int abort);
|
||||
extern "C" ANSLLM_API int ANSLLMSetLocalLLM(ANSCENTER::ANSLLM** Handle, int localLLM);
|
||||
extern "C" ANSLLM_API int ANSLLMSetOllamaBaseUrl(ANSCENTER::ANSLLM** Handle, const char* baseUrl);
|
||||
extern "C" ANSLLM_API int ANSLLMSetBaseURL(ANSCENTER::ANSLLM** Handle, const char* baseURL);
|
||||
|
||||
extern "C" ANSLLM_API int ANSLLMSetHeartbeatMs(ANSCENTER::ANSLLM** Handle, int heartbeatMs);
|
||||
extern "C" ANSLLM_API int ANSLLMGetHeartbeatMs(ANSCENTER::ANSLLM** Handle);
|
||||
extern "C" ANSLLM_API int ANSLLMSetHostedConversation(ANSCENTER::ANSLLM** Handle, int hostedConversationMode);
|
||||
extern "C" ANSLLM_API int ANSLLMGetHostedConversation(ANSCENTER::ANSLLM** Handle);
|
||||
|
||||
extern "C" ANSLLM_API int ANSLLMGetStreamingMode(ANSCENTER::ANSLLM** Handle);
|
||||
extern "C" ANSLLM_API int ANSLLMSetStreamingMode(ANSCENTER::ANSLLM** Handle, int streamingMode);
|
||||
extern "C" ANSLLM_API int ANSLLMGetIdleTimeoutMs(ANSCENTER::ANSLLM** Handle);
|
||||
extern "C" ANSLLM_API int ANSLLMSetIdleTimeoutMs(ANSCENTER::ANSLLM** Handle, int idleTimeoutMs);
|
||||
|
||||
extern "C" ANSLLM_API int ANSLLMSetSleepMs(ANSCENTER::ANSLLM** Handle, int sleepMs);
|
||||
extern "C" ANSLLM_API int ANSLLMGetLastErrorMessage(ANSCENTER::ANSLLM** Handle, LStrHandle LastErrorMessage);
|
||||
extern "C" ANSLLM_API int ANSLLMGetOutputText(ANSCENTER::ANSLLM** Handle, LStrHandle outputText);
|
||||
extern "C" ANSLLM_API int ANSLLMGetOutputTextSb(ANSCENTER::ANSLLM** Handle, LStrHandle outputTextSb);
|
||||
|
||||
|
||||
#endif
|
||||
30
modules/ANSLLM/CMakeLists.txt
Normal file
30
modules/ANSLLM/CMakeLists.txt
Normal file
@@ -0,0 +1,30 @@
|
||||
# ANSLLM — LLM Integration DLL
|
||||
add_library(ANSLLM SHARED
|
||||
ANSLLM.cpp
|
||||
ANSLLM.h
|
||||
dllmain.cpp
|
||||
pch.cpp
|
||||
pch.h
|
||||
framework.h
|
||||
)
|
||||
|
||||
target_include_directories(ANSLLM PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${SHARED_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(ANSLLM
|
||||
PRIVATE ANSLicensingSystem
|
||||
PRIVATE anslicensing
|
||||
PRIVATE labview
|
||||
PRIVATE opencv
|
||||
PRIVATE chilkat
|
||||
PRIVATE boost
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(ANSLLM PRIVATE ${WIN_COMMON_LIBS} crypt32)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(ANSLLM PRIVATE UNICODE _UNICODE ANSLLM_EXPORTS _USRDLL)
|
||||
target_precompile_headers(ANSLLM PRIVATE pch.h)
|
||||
1228
modules/ANSLLM/dllmain.cpp
Normal file
1228
modules/ANSLLM/dllmain.cpp
Normal file
File diff suppressed because it is too large
Load Diff
7
modules/ANSLLM/framework.h
Normal file
7
modules/ANSLLM/framework.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
#define NOMINMAX // Prevent windows.h from defining min/max macros
|
||||
// which break std::min / std::max (C2589)
|
||||
// Windows Header Files
|
||||
#include <windows.h>
|
||||
5
modules/ANSLLM/pch.cpp
Normal file
5
modules/ANSLLM/pch.cpp
Normal file
@@ -0,0 +1,5 @@
|
||||
// pch.cpp: source file corresponding to the pre-compiled header
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
|
||||
18
modules/ANSLLM/pch.h
Normal file
18
modules/ANSLLM/pch.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// pch.h: This is a precompiled header file.
|
||||
// Files listed below are compiled only once, improving build performance for future builds.
|
||||
// This also affects IntelliSense performance, including code completion and many code browsing features.
|
||||
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
|
||||
// Do not add files here that you will be updating frequently as this negates the performance advantage.
|
||||
|
||||
#ifndef PCH_H
|
||||
#define PCH_H
|
||||
|
||||
// add headers that you want to pre-compile here
|
||||
#include "framework.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
|
||||
#endif //PCH_H
|
||||
Reference in New Issue
Block a user