mirror of
				https://github.com/Palm1r/QodeAssist.git
				synced 2025-10-31 08:14:36 -04:00 
			
		
		
		
	Add OpenAI Compatible provider
This commit is contained in:
		| @ -38,6 +38,7 @@ add_qtc_plugin(QodeAssist | ||||
|     providers/LLMProvider.hpp | ||||
|     providers/OllamaProvider.hpp providers/OllamaProvider.cpp | ||||
|     providers/LMStudioProvider.hpp providers/LMStudioProvider.cpp | ||||
|     providers/OpenAICompatProvider.h providers/OpenAICompatProvider.cpp | ||||
|     LLMProvidersManager.hpp LLMProvidersManager.cpp | ||||
|     QodeAssistSettings.hpp QodeAssistSettings.cpp | ||||
|     QodeAssist.qrc | ||||
|  | ||||
| @ -54,6 +54,7 @@ const char MAX_FILE_THRESHOLD[] = "QodeAssist.maxFileThreshold"; | ||||
| const char OLLAMA_LIVETIME[] = "QodeAssist.ollamaLivetime"; | ||||
| const char SPECIFIC_INSTRUCTIONS[] = "QodeAssist.specificInstractions"; | ||||
| const char MULTILINE_COMPLETION[] = "QodeAssist.multilineCompletion"; | ||||
| const char API_KEY[] = "QodeAssist.apiKey"; | ||||
|  | ||||
| const char QODE_ASSIST_GENERAL_OPTIONS_ID[] = "QodeAssist.GeneralOptions"; | ||||
| const char QODE_ASSIST_GENERAL_OPTIONS_CATEGORY[] = "QodeAssist.Category"; | ||||
|  | ||||
| @ -123,15 +123,15 @@ QodeAssistSettings::QodeAssistSettings() | ||||
|     topP.setSettingsKey(Constants::TOP_P); | ||||
|     topP.setLabelText(Tr::tr("top_p")); | ||||
|     topP.setDefaultValue(0.9); | ||||
|     topP.setRange(0.0, 10.0); | ||||
|     topP.setRange(0.0, 1.0); | ||||
|  | ||||
|     useTopK.setSettingsKey(Constants::USE_TOP_K); | ||||
|     useTopK.setDefaultValue(false); | ||||
|  | ||||
|     topK.setSettingsKey(Constants::TOP_K); | ||||
|     topK.setLabelText(Tr::tr("top_k")); | ||||
|     topK.setDefaultValue(0.1); | ||||
|     topK.setRange(0, 10.0); | ||||
|     topK.setDefaultValue(50); | ||||
|     topK.setRange(1, 1000); | ||||
|  | ||||
|     usePresencePenalty.setSettingsKey(Constants::USE_PRESENCE_PENALTY); | ||||
|     usePresencePenalty.setDefaultValue(false); | ||||
| @ -170,6 +170,11 @@ QodeAssistSettings::QodeAssistSettings() | ||||
|     multiLineCompletion.setDefaultValue(true); | ||||
|     multiLineCompletion.setLabelText(Tr::tr("Enable Multiline Completion")); | ||||
|  | ||||
|     apiKey.setSettingsKey(Constants::API_KEY); | ||||
|     apiKey.setLabelText(Tr::tr("API Key:")); | ||||
|     apiKey.setDisplayStyle(Utils::StringAspect::LineEditDisplay); | ||||
|     apiKey.setPlaceHolderText(Tr::tr("Enter your API key here")); | ||||
|  | ||||
|     const auto &manager = LLMProvidersManager::instance(); | ||||
|     if (!manager.getProviderNames().isEmpty()) { | ||||
|         const auto providerNames = manager.getProviderNames(); | ||||
| @ -215,14 +220,15 @@ QodeAssistSettings::QodeAssistSettings() | ||||
|                             Form{Column{Row{selectModels, modelName}}}}, | ||||
|                       Group{title(Tr::tr("FIM Prompt Settings")), | ||||
|                             Form{Column{fimPrompts, | ||||
|                                         readFullFile, | ||||
|                                         maxFileThreshold, | ||||
|                                         readStringsBeforeCursor, | ||||
|                                         readStringsAfterCursor, | ||||
|                                         ollamaLivetime, | ||||
|                                         apiKey, | ||||
|                                         specificInstractions, | ||||
|                                         temperature, | ||||
|                                         maxTokens, | ||||
|                                         readFullFile, | ||||
|                                         readStringsBeforeCursor, | ||||
|                                         readStringsAfterCursor, | ||||
|                                         startSuggestionTimer, | ||||
|                                         Row{useTopP, topP, Stretch{1}}, | ||||
|                                         Row{useTopK, topK, Stretch{1}}, | ||||
|  | ||||
| @ -81,7 +81,7 @@ public: | ||||
|     Utils::DoubleAspect topP{this}; | ||||
|  | ||||
|     Utils::BoolAspect useTopK{this}; | ||||
|     Utils::DoubleAspect topK{this}; | ||||
|     Utils::IntegerAspect topK{this}; | ||||
|  | ||||
|     Utils::BoolAspect usePresencePenalty{this}; | ||||
|     Utils::DoubleAspect presencePenalty{this}; | ||||
| @ -98,6 +98,8 @@ public: | ||||
|     Utils::StringAspect specificInstractions{this}; | ||||
|     Utils::BoolAspect multiLineCompletion{this}; | ||||
|  | ||||
|     Utils::StringAspect apiKey{this}; | ||||
|  | ||||
|     ButtonAspect resetToDefaults{this}; | ||||
|  | ||||
| private: | ||||
|  | ||||
							
								
								
									
										129
									
								
								providers/OpenAICompatProvider.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								providers/OpenAICompatProvider.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,129 @@ | ||||
| /*  | ||||
|  * Copyright (C) 2024 Petr Mironychev | ||||
|  * | ||||
|  * This file is part of QodeAssist. | ||||
|  * | ||||
|  * QodeAssist is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * QodeAssist is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with QodeAssist. If not, see <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| #include "OpenAICompatProvider.h" | ||||
|  | ||||
| #include <QJsonArray> | ||||
| #include <QJsonDocument> | ||||
| #include <QJsonObject> | ||||
| #include <QNetworkReply> | ||||
| #include <QProcess> | ||||
|  | ||||
| #include "PromptTemplateManager.hpp" | ||||
| #include "QodeAssistSettings.hpp" | ||||
|  | ||||
| namespace QodeAssist::Providers { | ||||
|  | ||||
| OpenAICompatProvider::OpenAICompatProvider() {} | ||||
|  | ||||
| QString OpenAICompatProvider::name() const | ||||
| { | ||||
|     return "OpenAI Compatible"; | ||||
| } | ||||
|  | ||||
| QString OpenAICompatProvider::url() const | ||||
| { | ||||
|     return "http://localhost"; | ||||
| } | ||||
|  | ||||
| int OpenAICompatProvider::defaultPort() const | ||||
| { | ||||
|     return 1234; | ||||
| } | ||||
|  | ||||
| QString OpenAICompatProvider::completionEndpoint() const | ||||
| { | ||||
|     return "/v1/chat/completions"; | ||||
| } | ||||
|  | ||||
| void OpenAICompatProvider::prepareRequest(QJsonObject &request) | ||||
| { | ||||
|     const auto ¤tTemplate = PromptTemplateManager::instance().getCurrentTemplate(); | ||||
|  | ||||
|     if (request.contains("prompt")) { | ||||
|         QJsonArray messages{ | ||||
|             {QJsonObject{{"role", "user"}, {"content", request.take("prompt").toString()}}}}; | ||||
|         request["messages"] = std::move(messages); | ||||
|     } | ||||
|  | ||||
|     request["max_tokens"] = settings().maxTokens(); | ||||
|     request["temperature"] = settings().temperature(); | ||||
|     request["stop"] = QJsonArray::fromStringList(currentTemplate->stopWords()); | ||||
|     if (settings().useTopP()) | ||||
|         request["top_p"] = settings().topP(); | ||||
|     if (settings().useTopK()) | ||||
|         request["top_k"] = settings().topK(); | ||||
|     if (settings().useFrequencyPenalty()) | ||||
|         request["frequency_penalty"] = settings().frequencyPenalty(); | ||||
|     if (settings().usePresencePenalty()) | ||||
|         request["presence_penalty"] = settings().presencePenalty(); | ||||
|  | ||||
|     const QString &apiKey = settings().apiKey.value(); | ||||
|     if (!apiKey.isEmpty()) { | ||||
|         request["api_key"] = apiKey; | ||||
|     } | ||||
| } | ||||
|  | ||||
| bool OpenAICompatProvider::handleResponse(QNetworkReply *reply, QString &accumulatedResponse) | ||||
| { | ||||
|     bool isComplete = false; | ||||
|     while (reply->canReadLine()) { | ||||
|         QByteArray line = reply->readLine().trimmed(); | ||||
|         if (line.isEmpty()) { | ||||
|             continue; | ||||
|         } | ||||
|         if (line == "data: [DONE]") { | ||||
|             isComplete = true; | ||||
|             break; | ||||
|         } | ||||
|         if (line.startsWith("data: ")) { | ||||
|             line = line.mid(6); // Remove "data: " prefix | ||||
|         } | ||||
|         QJsonDocument jsonResponse = QJsonDocument::fromJson(line); | ||||
|         if (jsonResponse.isNull()) { | ||||
|             qWarning() << "Invalid JSON response from LM Studio:" << line; | ||||
|             continue; | ||||
|         } | ||||
|         QJsonObject responseObj = jsonResponse.object(); | ||||
|         if (responseObj.contains("choices")) { | ||||
|             QJsonArray choices = responseObj["choices"].toArray(); | ||||
|             if (!choices.isEmpty()) { | ||||
|                 QJsonObject choice = choices.first().toObject(); | ||||
|                 QJsonObject delta = choice["delta"].toObject(); | ||||
|                 if (delta.contains("content")) { | ||||
|                     QString completion = delta["content"].toString(); | ||||
|  | ||||
|                     accumulatedResponse += completion; | ||||
|                 } | ||||
|                 if (choice["finish_reason"].toString() == "stop") { | ||||
|                     isComplete = true; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return isComplete; | ||||
| } | ||||
|  | ||||
| QList<QString> OpenAICompatProvider::getInstalledModels(const Utils::Environment &env) | ||||
| { | ||||
|     return QStringList(); | ||||
| } | ||||
|  | ||||
| } // namespace QodeAssist::Providers | ||||
							
								
								
									
										40
									
								
								providers/OpenAICompatProvider.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								providers/OpenAICompatProvider.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | ||||
| /*  | ||||
|  * Copyright (C) 2024 Petr Mironychev | ||||
|  * | ||||
|  * This file is part of QodeAssist. | ||||
|  * | ||||
|  * QodeAssist is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * QodeAssist is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with QodeAssist. If not, see <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "LLMProvider.hpp" | ||||
|  | ||||
| namespace QodeAssist::Providers { | ||||
|  | ||||
| class OpenAICompatProvider : public LLMProvider | ||||
| { | ||||
| public: | ||||
|     OpenAICompatProvider(); | ||||
|  | ||||
|     QString name() const override; | ||||
|     QString url() const override; | ||||
|     int defaultPort() const override; | ||||
|     QString completionEndpoint() const override; | ||||
|     void prepareRequest(QJsonObject &request) override; | ||||
|     bool handleResponse(QNetworkReply *reply, QString &accumulatedResponse) override; | ||||
|     QList<QString> getInstalledModels(const Utils::Environment &env) override; | ||||
| }; | ||||
|  | ||||
| } // namespace QodeAssist::Providers | ||||
| @ -43,6 +43,7 @@ | ||||
| #include "QodeAssistClient.hpp" | ||||
| #include "providers/LMStudioProvider.hpp" | ||||
| #include "providers/OllamaProvider.hpp" | ||||
| #include "providers/OpenAICompatProvider.h" | ||||
| #include "templates/CodeLLamaTemplate.hpp" | ||||
| #include "templates/CodeQwenChat.hpp" | ||||
| #include "templates/StarCoder2Template.hpp" | ||||
| @ -73,6 +74,7 @@ public: | ||||
|         auto &providerManager = LLMProvidersManager::instance(); | ||||
|         providerManager.registerProvider<Providers::OllamaProvider>(); | ||||
|         providerManager.registerProvider<Providers::LMStudioProvider>(); | ||||
|         providerManager.registerProvider<Providers::OpenAICompatProvider>(); | ||||
|  | ||||
|         auto &templateManager = PromptTemplateManager::instance(); | ||||
|         templateManager.registerTemplate<Templates::CodeLLamaTemplate>(); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user