mirror of
https://github.com/Palm1r/QodeAssist.git
synced 2026-02-09 16:50:13 -05:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 19c25043fb | |||
| 56b5ea8e68 | |||
| b475f15e3d | |||
| 31f4516e7b | |||
| bfdbc755e3 | |||
| 30964d90d5 | |||
| 1261f913bb | |||
| 36d5242a1f | |||
| 6503887091 | |||
| 50087aa744 | |||
| 4f2dc0c450 | |||
| 80fe388bdd |
@ -40,14 +40,22 @@ add_qtc_plugin(QodeAssist
|
||||
QodeAssistConstants.hpp
|
||||
QodeAssisttr.h
|
||||
LLMClientInterface.hpp LLMClientInterface.cpp
|
||||
templates/Templates.hpp
|
||||
templates/CodeLlamaFim.hpp
|
||||
templates/StarCoder2Fim.hpp
|
||||
templates/DeepSeekCoderFim.hpp
|
||||
templates/CustomFimTemplate.hpp
|
||||
templates/DeepSeekCoderChat.hpp
|
||||
templates/CodeLlamaChat.hpp
|
||||
|
||||
|
||||
templates/Qwen.hpp
|
||||
templates/StarCoderChat.hpp
|
||||
|
||||
templates/Ollama.hpp
|
||||
templates/BasicChat.hpp
|
||||
templates/Llama3.hpp
|
||||
templates/ChatML.hpp
|
||||
templates/Alpaca.hpp
|
||||
templates/Llama2.hpp
|
||||
providers/Providers.hpp
|
||||
providers/OllamaProvider.hpp providers/OllamaProvider.cpp
|
||||
providers/LMStudioProvider.hpp providers/LMStudioProvider.cpp
|
||||
providers/OpenAICompatProvider.hpp providers/OpenAICompatProvider.cpp
|
||||
@ -62,5 +70,3 @@ add_qtc_plugin(QodeAssist
|
||||
chat/NavigationPanel.hpp chat/NavigationPanel.cpp
|
||||
ConfigurationManager.hpp ConfigurationManager.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(QodeAssist PRIVATE )
|
||||
|
||||
@ -68,15 +68,27 @@ void ClientInterface::sendMessage(const QString &message, bool includeCurrentFil
|
||||
{
|
||||
cancelRequest();
|
||||
|
||||
m_chatModel->addMessage(message, ChatModel::ChatRole::User, "");
|
||||
|
||||
auto &chatAssistantSettings = Settings::chatAssistantSettings();
|
||||
|
||||
auto providerName = Settings::generalSettings().caProvider();
|
||||
auto provider = LLMCore::ProvidersManager::instance().getProviderByName(providerName);
|
||||
|
||||
if (!provider) {
|
||||
LOG_MESSAGE(QString("No provider found with name: %1").arg(providerName));
|
||||
return;
|
||||
}
|
||||
|
||||
auto templateName = Settings::generalSettings().caTemplate();
|
||||
auto promptTemplate = LLMCore::PromptTemplateManager::instance().getChatTemplateByName(
|
||||
templateName);
|
||||
|
||||
if (!promptTemplate) {
|
||||
LOG_MESSAGE(QString("No template found with name: %1").arg(templateName));
|
||||
return;
|
||||
}
|
||||
|
||||
LLMCore::ContextData context;
|
||||
context.prefix = message;
|
||||
context.suffix = "";
|
||||
@ -114,11 +126,11 @@ void ClientInterface::sendMessage(const QString &message, bool includeCurrentFil
|
||||
config.url = QString("%1%2").arg(Settings::generalSettings().caUrl(), provider->chatEndpoint());
|
||||
config.providerRequest = providerRequest;
|
||||
config.multiLineCompletion = false;
|
||||
config.apiKey = Settings::chatAssistantSettings().apiKey();
|
||||
|
||||
QJsonObject request;
|
||||
request["id"] = QUuid::createUuid().toString();
|
||||
|
||||
m_chatModel->addMessage(message, ChatModel::ChatRole::User, "");
|
||||
m_requestHandler->sendLLMRequest(config, request);
|
||||
}
|
||||
|
||||
@ -138,11 +150,16 @@ void ClientInterface::handleLLMResponse(const QString &response,
|
||||
const QJsonObject &request,
|
||||
bool isComplete)
|
||||
{
|
||||
QString messageId = request["id"].toString();
|
||||
m_chatModel->addMessage(response.trimmed(), ChatModel::ChatRole::Assistant, messageId);
|
||||
const auto message = response.trimmed();
|
||||
|
||||
if (isComplete) {
|
||||
LOG_MESSAGE("Message completed. Final response for message " + messageId + ": " + response);
|
||||
if (!message.isEmpty()) {
|
||||
QString messageId = request["id"].toString();
|
||||
m_chatModel->addMessage(message, ChatModel::ChatRole::Assistant, messageId);
|
||||
|
||||
if (isComplete) {
|
||||
LOG_MESSAGE(
|
||||
"Message completed. Final response for message " + messageId + ": " + response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -210,10 +210,11 @@ LLMCore::ContextData DocumentContextReader::prepareContext(int lineNumber, int c
|
||||
|
||||
QString fileContext;
|
||||
if (Settings::codeCompletionSettings().useFilePathInContext())
|
||||
fileContext += getLanguageAndFileInfo();
|
||||
fileContext.append("\n ").append(getLanguageAndFileInfo());
|
||||
|
||||
if (Settings::codeCompletionSettings().useProjectChangesCache())
|
||||
fileContext += ChangesManager::instance().getRecentChangesContext(m_textDocument);
|
||||
fileContext.append("\n ").append(
|
||||
ChangesManager::instance().getRecentChangesContext(m_textDocument));
|
||||
|
||||
return {contextBefore, contextAfter, fileContext};
|
||||
}
|
||||
|
||||
@ -152,21 +152,30 @@ void LLMClientInterface::handleCompletion(const QJsonObject &request)
|
||||
auto providerName = Settings::generalSettings().ccProvider();
|
||||
auto provider = LLMCore::ProvidersManager::instance().getProviderByName(providerName);
|
||||
|
||||
if (!provider) {
|
||||
LOG_MESSAGE(QString("No provider found with name: %1").arg(providerName));
|
||||
return;
|
||||
}
|
||||
|
||||
auto templateName = Settings::generalSettings().ccTemplate();
|
||||
auto promptTemplate = LLMCore::PromptTemplateManager::instance().getFimTemplateByName(
|
||||
templateName);
|
||||
|
||||
if (!promptTemplate) {
|
||||
LOG_MESSAGE(QString("No template found with name: %1").arg(templateName));
|
||||
return;
|
||||
}
|
||||
|
||||
LLMCore::LLMConfig config;
|
||||
config.requestType = LLMCore::RequestType::Fim;
|
||||
config.provider = provider;
|
||||
config.promptTemplate = promptTemplate;
|
||||
config.url = QUrl(
|
||||
QString("%1%2").arg(Settings::generalSettings().ccUrl(), provider->completionEndpoint()));
|
||||
config.apiKey = Settings::codeCompletionSettings().apiKey();
|
||||
|
||||
config.providerRequest = {{"model", Settings::generalSettings().ccModel()}, {"stream", true}};
|
||||
|
||||
config.providerRequest = {{"model", Settings::generalSettings().ccModel()},
|
||||
{"stream", true},
|
||||
{"stop",
|
||||
QJsonArray::fromStringList(config.promptTemplate->stopWords())}};
|
||||
config.multiLineCompletion = completeSettings.multiLineCompletion();
|
||||
|
||||
QString systemPrompt;
|
||||
@ -174,8 +183,12 @@ void LLMClientInterface::handleCompletion(const QJsonObject &request)
|
||||
systemPrompt.append(completeSettings.systemPrompt());
|
||||
if (!updatedContext.fileContext.isEmpty())
|
||||
systemPrompt.append(updatedContext.fileContext);
|
||||
if (!systemPrompt.isEmpty())
|
||||
config.providerRequest["system"] = systemPrompt;
|
||||
|
||||
config.providerRequest["system"] = systemPrompt;
|
||||
const auto stopWords = QJsonArray::fromStringList(config.promptTemplate->stopWords());
|
||||
if (!stopWords.isEmpty())
|
||||
config.providerRequest["stop"] = stopWords;
|
||||
|
||||
config.promptTemplate->prepareRequest(config.providerRequest, updatedContext);
|
||||
config.provider->prepareRequest(config.providerRequest, LLMCore::RequestType::Fim);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"Name" : "QodeAssist",
|
||||
"Version" : "0.3.8",
|
||||
"Version" : "0.3.10",
|
||||
"CompatVersion" : "${IDE_VERSION_COMPAT}",
|
||||
"Vendor" : "Petr Mironychev",
|
||||
"Copyright" : "(C) ${IDE_COPYRIGHT_YEAR} Petr Mironychev, (C) ${IDE_COPYRIGHT_YEAR} The Qt Company Ltd",
|
||||
|
||||
50
README.md
50
README.md
@ -30,7 +30,7 @@ QodeAssist is an AI-powered coding assistant plugin for Qt Creator. It provides
|
||||
- Support for multiple LLM providers:
|
||||
- Ollama
|
||||
- LM Studio
|
||||
- OpenAI-compatible local providers
|
||||
- OpenAI-compatible providers(eg. https://openrouter.ai)
|
||||
- Extensive library of model-specific templates
|
||||
- Custom template support
|
||||
- Easy configuration and model selection
|
||||
@ -56,13 +56,17 @@ QodeAssist is an AI-powered coding assistant plugin for Qt Creator. It provides
|
||||
2. Install [Ollama](https://ollama.com). Make sure to review the system requirements before installation.
|
||||
3. Install a language models in Ollama via terminal. For example, you can run:
|
||||
|
||||
For suggestions:
|
||||
For standard computers (minimum 8GB RAM):
|
||||
```
|
||||
ollama run codellama:7b-code
|
||||
ollama run qwen2.5-coder:7b
|
||||
```
|
||||
For chat:
|
||||
For better performance (16GB+ RAM):
|
||||
```
|
||||
ollama run codellama:7b-instruct
|
||||
ollama run qwen2.5-coder:14b
|
||||
```
|
||||
For high-end systems (32GB+ RAM):
|
||||
```
|
||||
ollama run qwen2.5-coder:32b
|
||||
```
|
||||
4. Download the QodeAssist plugin for your QtCreator.
|
||||
5. Launch Qt Creator and install the plugin:
|
||||
@ -73,38 +77,32 @@ ollama run codellama:7b-instruct
|
||||
|
||||
## Configure Plugin
|
||||
|
||||
<details>
|
||||
<summary>Configure plugins: (click to expand)</summary>
|
||||
<img src="https://github.com/user-attachments/assets/00ad980f-b470-48eb-9aaa-077783d38798" width="600" alt="Configuere QodeAssist">
|
||||
</details>
|
||||
QodeAssist comes with default settings that should work immediately after installing a language model. The plugin is pre-configured to use Ollama with standard templates, so you may only need to verify the settings.
|
||||
|
||||
1. Open Qt Creator settings
|
||||
1. Open Qt Creator settings (Edit > Preferences on Linux/Windows, Qt Creator > Preferences on macOS)
|
||||
2. Navigate to the "Qode Assist" tab
|
||||
3. Select "General" page
|
||||
4. Choose your LLM provider (e.g., Ollama)
|
||||
5. Select the installed model by the "Select Model" button
|
||||
- For LM Studio you will see current loaded model
|
||||
6. Choose the prompt template that corresponds to your model
|
||||
7. Apply the settings
|
||||
3. On the "General" page, verify:
|
||||
- Ollama is selected as your LLM provider
|
||||
- The URL is set to http://localhost:11434
|
||||
- Your installed model appears in the model selection
|
||||
- The prompt template is Ollama Auto FIM
|
||||
4. Click Apply if you made any changes
|
||||
|
||||
You're all set! QodeAssist is now ready to use in Qt Creator.
|
||||
|
||||
[](https://ko-fi.com/P5P412V96G)
|
||||
|
||||
## Supported LLM Providers
|
||||
QodeAssist currently supports the following LLM (Large Language Model) providers:
|
||||
- [Ollama](https://ollama.com)
|
||||
- [LM Studio](https://lmstudio.ai)
|
||||
- OpenAI compatible providers
|
||||
- [LM Studio](https://lmstudio.ai) (experimental)
|
||||
- OpenAI compatible providers (experimental)
|
||||
|
||||
## Recommended Models:
|
||||
QodeAssist has been thoroughly tested and optimized for use with the following language models:
|
||||
|
||||
- Llama
|
||||
- Qwen2.5-coder
|
||||
- CodeLlama
|
||||
- StarCoder2
|
||||
- DeepSeek-Coder-V2
|
||||
- Qwen-2.5
|
||||
|
||||
### Ollama:
|
||||
### For autocomplete(FIM)
|
||||
@ -122,13 +120,6 @@ ollama run qwen2.5-coder:7b-instruct
|
||||
ollama run deepseek-coder-v2
|
||||
```
|
||||
|
||||
### LM Studio:
|
||||
similar models, like for ollama
|
||||
|
||||
Please note that while these models have been specifically tested and confirmed to work well with QodeAssist, other models compatible with the supported providers may also work. We encourage users to experiment with different models and report their experiences.
|
||||
|
||||
If you've successfully used a model that's not listed here, please let us know by opening an issue or submitting a pull request to update this list.
|
||||
|
||||
## QtCreator Version Compatibility
|
||||
|
||||
- QtCreator 14.0.2 - 0.2.3 - 0.3.x
|
||||
@ -191,7 +182,6 @@ If you find QodeAssist helpful, there are several ways you can support the proje
|
||||
3. **Spread the Word**: Star our GitHub repository and share QodeAssist with your fellow developers.
|
||||
|
||||
4. **Financial Support**: If you'd like to support the development financially, you can make a donation using one of the following:
|
||||
- [](https://ko-fi.com/P5P412V96G)
|
||||
- Bitcoin (BTC): `bc1qndq7f0mpnlya48vk7kugvyqj5w89xrg4wzg68t`
|
||||
- Ethereum (ETH): `0xA5e8c37c94b24e25F9f1f292a01AF55F03099D8D`
|
||||
- Litecoin (LTC): `ltc1qlrxnk30s2pcjchzx4qrxvdjt5gzuervy5mv0vy`
|
||||
|
||||
@ -38,5 +38,6 @@ public:
|
||||
virtual QString promptTemplate() const = 0;
|
||||
virtual QStringList stopWords() const = 0;
|
||||
virtual void prepareRequest(QJsonObject &request, const ContextData &context) const = 0;
|
||||
virtual QString description() const = 0;
|
||||
};
|
||||
} // namespace QodeAssist::LLMCore
|
||||
|
||||
@ -35,6 +35,7 @@ struct LLMConfig
|
||||
QJsonObject providerRequest;
|
||||
RequestType requestType;
|
||||
bool multiLineCompletion;
|
||||
QString apiKey;
|
||||
};
|
||||
|
||||
} // namespace QodeAssist::LLMCore
|
||||
|
||||
@ -38,7 +38,8 @@ void RequestHandler::sendLLMRequest(const LLMConfig &config, const QJsonObject &
|
||||
QJsonDocument(config.providerRequest).toJson(QJsonDocument::Indented))));
|
||||
|
||||
QNetworkRequest networkRequest(config.url);
|
||||
prepareNetworkRequest(networkRequest, config.providerRequest);
|
||||
if (!config.apiKey.isEmpty())
|
||||
prepareNetworkRequest(networkRequest, config.apiKey);
|
||||
|
||||
QNetworkReply *reply = m_manager->post(networkRequest,
|
||||
QJsonDocument(config.providerRequest).toJson());
|
||||
@ -84,6 +85,8 @@ void RequestHandler::handleLLMResponse(QNetworkReply *reply,
|
||||
if (isComplete) {
|
||||
auto cleanedCompletion = removeStopWords(accumulatedResponse,
|
||||
config.promptTemplate->stopWords());
|
||||
removeCodeBlockWrappers(cleanedCompletion);
|
||||
|
||||
emit completionReceived(cleanedCompletion, request, true);
|
||||
}
|
||||
} else if (config.requestType == RequestType::Chat) {
|
||||
@ -107,33 +110,30 @@ bool RequestHandler::cancelRequest(const QString &id)
|
||||
return false;
|
||||
}
|
||||
|
||||
void RequestHandler::prepareNetworkRequest(QNetworkRequest &networkRequest,
|
||||
const QJsonObject &providerRequest)
|
||||
void RequestHandler::prepareNetworkRequest(
|
||||
QNetworkRequest &networkRequest, const QString &apiKey) const
|
||||
{
|
||||
networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
|
||||
if (providerRequest.contains("api_key")) {
|
||||
QString apiKey = providerRequest["api_key"].toString();
|
||||
networkRequest.setRawHeader("Authorization", QString("Bearer %1").arg(apiKey).toUtf8());
|
||||
}
|
||||
networkRequest.setRawHeader("Authorization", QString("Bearer %1").arg(apiKey).toUtf8());
|
||||
}
|
||||
|
||||
bool RequestHandler::processSingleLineCompletion(QNetworkReply *reply,
|
||||
const QJsonObject &request,
|
||||
const QString &accumulatedResponse,
|
||||
const LLMConfig &config)
|
||||
bool RequestHandler::processSingleLineCompletion(
|
||||
QNetworkReply *reply,
|
||||
const QJsonObject &request,
|
||||
const QString &accumulatedResponse,
|
||||
const LLMConfig &config)
|
||||
{
|
||||
int newlinePos = accumulatedResponse.indexOf('\n');
|
||||
QString cleanedResponse = accumulatedResponse;
|
||||
removeCodeBlockWrappers(cleanedResponse);
|
||||
|
||||
int newlinePos = cleanedResponse.indexOf('\n');
|
||||
if (newlinePos != -1) {
|
||||
QString singleLineCompletion = accumulatedResponse.left(newlinePos).trimmed();
|
||||
singleLineCompletion = removeStopWords(singleLineCompletion,
|
||||
config.promptTemplate->stopWords());
|
||||
|
||||
QString singleLineCompletion = cleanedResponse.left(newlinePos).trimmed();
|
||||
singleLineCompletion
|
||||
= removeStopWords(singleLineCompletion, config.promptTemplate->stopWords());
|
||||
emit completionReceived(singleLineCompletion, request, true);
|
||||
m_accumulatedResponses.remove(reply);
|
||||
reply->abort();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -150,4 +150,36 @@ QString RequestHandler::removeStopWords(const QStringView &completion, const QSt
|
||||
return filteredCompletion;
|
||||
}
|
||||
|
||||
void RequestHandler::removeCodeBlockWrappers(QString &response)
|
||||
{
|
||||
static const QRegularExpression
|
||||
fullCodeBlockRegex(R"(```[\w\s]*\n([\s\S]*?)```)", QRegularExpression::MultilineOption);
|
||||
static const QRegularExpression
|
||||
partialStartBlockRegex(R"(```[\w\s]*\n([\s\S]*?)$)", QRegularExpression::MultilineOption);
|
||||
static const QRegularExpression
|
||||
partialEndBlockRegex(R"(^([\s\S]*?)```)", QRegularExpression::MultilineOption);
|
||||
|
||||
QRegularExpressionMatchIterator matchIterator = fullCodeBlockRegex.globalMatch(response);
|
||||
while (matchIterator.hasNext()) {
|
||||
QRegularExpressionMatch match = matchIterator.next();
|
||||
QString codeBlock = match.captured(0);
|
||||
QString codeContent = match.captured(1).trimmed();
|
||||
response.replace(codeBlock, codeContent);
|
||||
}
|
||||
|
||||
QRegularExpressionMatch startMatch = partialStartBlockRegex.match(response);
|
||||
if (startMatch.hasMatch()) {
|
||||
QString partialBlock = startMatch.captured(0);
|
||||
QString codeContent = startMatch.captured(1).trimmed();
|
||||
response.replace(partialBlock, codeContent);
|
||||
}
|
||||
|
||||
QRegularExpressionMatch endMatch = partialEndBlockRegex.match(response);
|
||||
if (endMatch.hasMatch()) {
|
||||
QString partialBlock = endMatch.captured(0);
|
||||
QString codeContent = endMatch.captured(1).trimmed();
|
||||
response.replace(partialBlock, codeContent);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace QodeAssist::LLMCore
|
||||
|
||||
@ -52,12 +52,13 @@ private:
|
||||
QMap<QString, QNetworkReply *> m_activeRequests;
|
||||
QMap<QNetworkReply *, QString> m_accumulatedResponses;
|
||||
|
||||
void prepareNetworkRequest(QNetworkRequest &networkRequest, const QJsonObject &providerRequest);
|
||||
void prepareNetworkRequest(QNetworkRequest &networkRequest, const QString &apiKey) const;
|
||||
bool processSingleLineCompletion(QNetworkReply *reply,
|
||||
const QJsonObject &request,
|
||||
const QString &accumulatedResponse,
|
||||
const LLMConfig &config);
|
||||
QString removeStopWords(const QStringView &completion, const QStringList &stopWords);
|
||||
void removeCodeBlockWrappers(QString &response);
|
||||
};
|
||||
|
||||
} // namespace QodeAssist::LLMCore
|
||||
|
||||
@ -26,13 +26,15 @@
|
||||
#include <QJsonObject>
|
||||
#include <QNetworkReply>
|
||||
|
||||
#include "logger/Logger.hpp"
|
||||
|
||||
namespace QodeAssist::Providers {
|
||||
|
||||
OpenAICompatProvider::OpenAICompatProvider() {}
|
||||
|
||||
QString OpenAICompatProvider::name() const
|
||||
{
|
||||
return "OpenAI Compatible (experimental)";
|
||||
return "OpenAI Compatible";
|
||||
}
|
||||
|
||||
QString OpenAICompatProvider::url() const
|
||||
@ -82,10 +84,6 @@ void OpenAICompatProvider::prepareRequest(QJsonObject &request, LLMCore::Request
|
||||
request["frequency_penalty"] = settings.frequencyPenalty();
|
||||
if (settings.usePresencePenalty())
|
||||
request["presence_penalty"] = settings.presencePenalty();
|
||||
const QString &apiKey = settings.apiKey();
|
||||
if (!apiKey.isEmpty()) {
|
||||
request["api_key"] = apiKey;
|
||||
}
|
||||
};
|
||||
|
||||
QJsonArray messages = prepareMessages(request);
|
||||
@ -103,24 +101,41 @@ void OpenAICompatProvider::prepareRequest(QJsonObject &request, LLMCore::Request
|
||||
bool OpenAICompatProvider::handleResponse(QNetworkReply *reply, QString &accumulatedResponse)
|
||||
{
|
||||
bool isComplete = false;
|
||||
QString tempResponse = accumulatedResponse;
|
||||
|
||||
while (reply->canReadLine()) {
|
||||
QByteArray line = reply->readLine().trimmed();
|
||||
if (line.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (line == "data: [DONE]") {
|
||||
|
||||
if (!line.startsWith("data:")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
line = line.mid(6);
|
||||
|
||||
if (line == "[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;
|
||||
LOG_MESSAGE(
|
||||
"Invalid JSON response from OpenAI compatible provider: " + QString::fromUtf8(line));
|
||||
continue;
|
||||
}
|
||||
|
||||
QJsonObject responseObj = jsonResponse.object();
|
||||
|
||||
if (responseObj.contains("error")) {
|
||||
LOG_MESSAGE(
|
||||
"OpenAI compatible provider error: "
|
||||
+ QString::fromUtf8(QJsonDocument(responseObj).toJson(QJsonDocument::Indented)));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (responseObj.contains("choices")) {
|
||||
QJsonArray choices = responseObj["choices"].toArray();
|
||||
if (!choices.isEmpty()) {
|
||||
@ -128,16 +143,30 @@ bool OpenAICompatProvider::handleResponse(QNetworkReply *reply, QString &accumul
|
||||
QJsonObject delta = choice["delta"].toObject();
|
||||
if (delta.contains("content")) {
|
||||
QString completion = delta["content"].toString();
|
||||
|
||||
accumulatedResponse += completion;
|
||||
if (!completion.isEmpty()) {
|
||||
tempResponse += completion;
|
||||
}
|
||||
}
|
||||
if (choice["finish_reason"].toString() == "stop") {
|
||||
QString finishReason = choice["finish_reason"].toString();
|
||||
if (!finishReason.isNull() && finishReason == "stop") {
|
||||
isComplete = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (responseObj.contains("usage")) {
|
||||
QJsonObject usage = responseObj["usage"].toObject();
|
||||
LOG_MESSAGE(QString("Token usage - Prompt: %1, Completion: %2, Total: %3")
|
||||
.arg(usage["prompt_tokens"].toInt())
|
||||
.arg(usage["completion_tokens"].toInt())
|
||||
.arg(usage["total_tokens"].toInt()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!tempResponse.isEmpty()) {
|
||||
accumulatedResponse = tempResponse;
|
||||
}
|
||||
|
||||
return isComplete;
|
||||
}
|
||||
|
||||
|
||||
37
providers/Providers.hpp
Normal file
37
providers/Providers.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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 "llmcore/ProvidersManager.hpp"
|
||||
#include "providers/LMStudioProvider.hpp"
|
||||
#include "providers/OllamaProvider.hpp"
|
||||
#include "providers/OpenAICompatProvider.hpp"
|
||||
|
||||
namespace QodeAssist::Providers {
|
||||
|
||||
inline void registerProviders()
|
||||
{
|
||||
auto &providerManager = LLMCore::ProvidersManager::instance();
|
||||
providerManager.registerProvider<OllamaProvider>();
|
||||
providerManager.registerProvider<LMStudioProvider>();
|
||||
providerManager.registerProvider<OpenAICompatProvider>();
|
||||
}
|
||||
|
||||
} // namespace QodeAssist::Providers
|
||||
@ -43,20 +43,9 @@
|
||||
#include "QodeAssistClient.hpp"
|
||||
#include "chat/ChatOutputPane.h"
|
||||
#include "chat/NavigationPanel.hpp"
|
||||
#include "llmcore/PromptTemplateManager.hpp"
|
||||
#include "llmcore/ProvidersManager.hpp"
|
||||
#include "providers/LMStudioProvider.hpp"
|
||||
#include "providers/OllamaProvider.hpp"
|
||||
#include "providers/OpenAICompatProvider.hpp"
|
||||
|
||||
#include "templates/CodeLlamaChat.hpp"
|
||||
#include "templates/CodeLlamaFim.hpp"
|
||||
#include "templates/CustomFimTemplate.hpp"
|
||||
#include "templates/DeepSeekCoderChat.hpp"
|
||||
#include "templates/DeepSeekCoderFim.hpp"
|
||||
#include "templates/Qwen.hpp"
|
||||
#include "templates/StarCoder2Fim.hpp"
|
||||
#include "templates/StarCoderChat.hpp"
|
||||
#include "providers/Providers.hpp"
|
||||
#include "templates/Templates.hpp"
|
||||
|
||||
using namespace Utils;
|
||||
using namespace Core;
|
||||
@ -83,22 +72,8 @@ public:
|
||||
|
||||
void initialize() final
|
||||
{
|
||||
auto &providerManager = LLMCore::ProvidersManager::instance();
|
||||
providerManager.registerProvider<Providers::OllamaProvider>();
|
||||
providerManager.registerProvider<Providers::LMStudioProvider>();
|
||||
providerManager.registerProvider<Providers::OpenAICompatProvider>();
|
||||
|
||||
auto &templateManager = LLMCore::PromptTemplateManager::instance();
|
||||
templateManager.registerTemplate<Templates::CodeLlamaFim>();
|
||||
templateManager.registerTemplate<Templates::StarCoder2Fim>();
|
||||
templateManager.registerTemplate<Templates::DeepSeekCoderFim>();
|
||||
templateManager.registerTemplate<Templates::CustomTemplate>();
|
||||
templateManager.registerTemplate<Templates::DeepSeekCoderChat>();
|
||||
templateManager.registerTemplate<Templates::CodeLlamaChat>();
|
||||
templateManager.registerTemplate<Templates::LlamaChat>();
|
||||
templateManager.registerTemplate<Templates::StarCoderChat>();
|
||||
templateManager.registerTemplate<Templates::QwenChat>();
|
||||
templateManager.registerTemplate<Templates::QwenFim>();
|
||||
Providers::registerProviders();
|
||||
Templates::registerTemplates();
|
||||
|
||||
Utils::Icon QCODEASSIST_ICON(
|
||||
{{":/resources/images/qoderassist-icon.png", Utils::Theme::IconsBaseColor}});
|
||||
|
||||
@ -143,9 +143,8 @@ CodeCompletionSettings::CodeCompletionSettings()
|
||||
|
||||
systemPrompt.setSettingsKey(Constants::CC_SYSTEM_PROMPT);
|
||||
systemPrompt.setDisplayStyle(Utils::StringAspect::TextEditDisplay);
|
||||
systemPrompt.setDefaultValue(
|
||||
"You are an expert C++, Qt, and QML code completion AI. Your task is to provide accurate "
|
||||
"and contextually appropriate code suggestions.");
|
||||
systemPrompt.setDefaultValue("You are an expert C++, Qt, and QML code completion AI. ANSWER "
|
||||
"should be SHORT and in CODE");
|
||||
|
||||
useFilePathInContext.setSettingsKey(Constants::CC_USE_FILE_PATH_IN_CONTEXT);
|
||||
useFilePathInContext.setDefaultValue(true);
|
||||
|
||||
@ -66,11 +66,11 @@ GeneralSettings::GeneralSettings()
|
||||
ccProvider.setReadOnly(true);
|
||||
ccSelectProvider.m_buttonText = TrConstants::SELECT;
|
||||
|
||||
initStringAspect(ccModel, Constants::CC_MODEL, TrConstants::MODEL, "codellama:7b-code");
|
||||
initStringAspect(ccModel, Constants::CC_MODEL, TrConstants::MODEL, "qwen2.5-coder:7b");
|
||||
ccModel.setHistoryCompleter(Constants::CC_MODEL_HISTORY);
|
||||
ccSelectModel.m_buttonText = TrConstants::SELECT;
|
||||
|
||||
initStringAspect(ccTemplate, Constants::CC_TEMPLATE, TrConstants::TEMPLATE, "CodeLlama FIM");
|
||||
initStringAspect(ccTemplate, Constants::CC_TEMPLATE, TrConstants::TEMPLATE, "Ollama Auto FIM");
|
||||
ccTemplate.setReadOnly(true);
|
||||
ccSelectTemplate.m_buttonText = TrConstants::SELECT;
|
||||
|
||||
@ -87,11 +87,11 @@ GeneralSettings::GeneralSettings()
|
||||
caProvider.setReadOnly(true);
|
||||
caSelectProvider.m_buttonText = TrConstants::SELECT;
|
||||
|
||||
initStringAspect(caModel, Constants::CA_MODEL, TrConstants::MODEL, "codellama:7b-instruct");
|
||||
initStringAspect(caModel, Constants::CA_MODEL, TrConstants::MODEL, "qwen2.5-coder:7b");
|
||||
caModel.setHistoryCompleter(Constants::CA_MODEL_HISTORY);
|
||||
caSelectModel.m_buttonText = TrConstants::SELECT;
|
||||
|
||||
initStringAspect(caTemplate, Constants::CA_TEMPLATE, TrConstants::TEMPLATE, "CodeLlama Chat");
|
||||
initStringAspect(caTemplate, Constants::CA_TEMPLATE, TrConstants::TEMPLATE, "Ollama Auto Chat");
|
||||
caTemplate.setReadOnly(true);
|
||||
|
||||
caSelectTemplate.m_buttonText = TrConstants::SELECT;
|
||||
|
||||
67
templates/Alpaca.hpp
Normal file
67
templates/Alpaca.hpp
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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 "llmcore/PromptTemplate.hpp"
|
||||
#include <QJsonArray>
|
||||
|
||||
namespace QodeAssist::Templates {
|
||||
|
||||
class Alpaca : public LLMCore::PromptTemplate
|
||||
{
|
||||
public:
|
||||
QString name() const override { return "Alpaca"; }
|
||||
LLMCore::TemplateType type() const override { return LLMCore::TemplateType::Chat; }
|
||||
QString promptTemplate() const override { return {}; }
|
||||
QStringList stopWords() const override
|
||||
{
|
||||
return QStringList() << "### Instruction:" << "### Response:";
|
||||
}
|
||||
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
||||
{
|
||||
QJsonArray messages = request["messages"].toArray();
|
||||
|
||||
for (int i = 0; i < messages.size(); ++i) {
|
||||
QJsonObject message = messages[i].toObject();
|
||||
QString role = message["role"].toString();
|
||||
QString content = message["content"].toString();
|
||||
|
||||
QString formattedContent;
|
||||
if (role == "system") {
|
||||
formattedContent = content + "\n\n";
|
||||
} else if (role == "user") {
|
||||
formattedContent = "### Instruction:\n" + content + "\n\n";
|
||||
} else if (role == "assistant") {
|
||||
formattedContent = "### Response:\n" + content + "\n\n";
|
||||
}
|
||||
|
||||
message["content"] = formattedContent;
|
||||
messages[i] = message;
|
||||
}
|
||||
|
||||
request["messages"] = messages;
|
||||
}
|
||||
QString description() const override
|
||||
{
|
||||
return "The message will contain the following tokens: ### Instruction:\n### Response:\n";
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace QodeAssist::Templates
|
||||
@ -19,37 +19,22 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/qjsonarray.h>
|
||||
#include <QJsonArray>
|
||||
|
||||
#include "llmcore/PromptTemplate.hpp"
|
||||
|
||||
namespace QodeAssist::Templates {
|
||||
|
||||
class CodeLlamaChat : public LLMCore::PromptTemplate
|
||||
class BasicChat : public LLMCore::PromptTemplate
|
||||
{
|
||||
public:
|
||||
LLMCore::TemplateType type() const override { return LLMCore::TemplateType::Chat; }
|
||||
QString name() const override { return "CodeLlama Chat"; }
|
||||
QString promptTemplate() const override { return "[INST] %1 [/INST]"; }
|
||||
QStringList stopWords() const override { return QStringList() << "[INST]" << "[/INST]"; }
|
||||
|
||||
QString name() const override { return "Basic Chat"; }
|
||||
QString promptTemplate() const override { return {}; }
|
||||
QStringList stopWords() const override { return QStringList(); }
|
||||
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
||||
{
|
||||
QString formattedPrompt = promptTemplate().arg(context.prefix);
|
||||
QJsonArray messages = request["messages"].toArray();
|
||||
|
||||
QJsonObject newMessage;
|
||||
newMessage["role"] = "user";
|
||||
newMessage["content"] = formattedPrompt;
|
||||
messages.append(newMessage);
|
||||
|
||||
request["messages"] = messages;
|
||||
}
|
||||
};
|
||||
|
||||
class LlamaChat : public CodeLlamaChat
|
||||
{
|
||||
public:
|
||||
QString name() const override { return "Llama Chat"; }
|
||||
{}
|
||||
QString description() const override { return "chat without tokens"; }
|
||||
};
|
||||
|
||||
} // namespace QodeAssist::Templates
|
||||
@ -20,35 +20,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <QJsonArray>
|
||||
|
||||
#include "llmcore/PromptTemplate.hpp"
|
||||
|
||||
namespace QodeAssist::Templates {
|
||||
|
||||
class DeepSeekCoderChat : public LLMCore::PromptTemplate
|
||||
class ChatML : public LLMCore::PromptTemplate
|
||||
{
|
||||
public:
|
||||
QString name() const override { return "DeepSeekCoder Chat"; }
|
||||
QString name() const override { return "ChatML"; }
|
||||
LLMCore::TemplateType type() const override { return LLMCore::TemplateType::Chat; }
|
||||
|
||||
QString promptTemplate() const override { return "### Instruction:\n%1\n### Response:\n"; }
|
||||
|
||||
QString promptTemplate() const override { return {}; }
|
||||
QStringList stopWords() const override
|
||||
{
|
||||
return QStringList() << "### Instruction:" << "### Response:" << "\n\n### " << "<|EOT|>";
|
||||
return QStringList() << "<|im_start|>" << "<|im_end|>";
|
||||
}
|
||||
|
||||
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
||||
{
|
||||
QString formattedPrompt = promptTemplate().arg(context.prefix);
|
||||
QJsonArray messages = request["messages"].toArray();
|
||||
|
||||
QJsonObject newMessage;
|
||||
newMessage["role"] = "user";
|
||||
newMessage["content"] = formattedPrompt;
|
||||
messages.append(newMessage);
|
||||
for (int i = 0; i < messages.size(); ++i) {
|
||||
QJsonObject message = messages[i].toObject();
|
||||
QString role = message["role"].toString();
|
||||
QString content = message["content"].toString();
|
||||
|
||||
message["content"] = QString("<|im_start|>%1\n%2\n<|im_end|>").arg(role, content);
|
||||
|
||||
messages[i] = message;
|
||||
}
|
||||
|
||||
request["messages"] = messages;
|
||||
}
|
||||
QString description() const override
|
||||
{
|
||||
return "The message will contain the following tokens: <|im_start|>%1\n%2\n<|im_end|>";
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace QodeAssist::Templates
|
||||
@ -33,12 +33,15 @@ public:
|
||||
{
|
||||
return QStringList() << "<EOT>" << "<PRE>" << "<SUF" << "<MID>";
|
||||
}
|
||||
|
||||
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
||||
{
|
||||
QString formattedPrompt = promptTemplate().arg(context.prefix, context.suffix);
|
||||
request["prompt"] = formattedPrompt;
|
||||
}
|
||||
QString description() const override
|
||||
{
|
||||
return "The message will contain the following tokens: <PRE> %1 <SUF>%2 <MID>";
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace QodeAssist::Templates
|
||||
|
||||
@ -39,7 +39,6 @@ public:
|
||||
return Settings::customPromptSettings().customJsonTemplate();
|
||||
}
|
||||
QStringList stopWords() const override { return QStringList(); }
|
||||
|
||||
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
||||
{
|
||||
QJsonDocument doc = QJsonDocument::fromJson(promptTemplate().toUtf8());
|
||||
@ -56,6 +55,7 @@ public:
|
||||
request[it.key()] = it.value();
|
||||
}
|
||||
}
|
||||
QString description() const override { return promptTemplate(); }
|
||||
|
||||
private:
|
||||
QJsonValue processJsonValue(const QJsonValue &value, const LLMCore::ContextData &context) const
|
||||
|
||||
@ -38,6 +38,11 @@ public:
|
||||
QString formattedPrompt = promptTemplate().arg(context.prefix, context.suffix);
|
||||
request["prompt"] = formattedPrompt;
|
||||
}
|
||||
QString description() const override
|
||||
{
|
||||
return "The message will contain the following tokens: "
|
||||
"<|fim▁begin|>%1<|fim▁hole|>%2<|fim▁end|>";
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace QodeAssist::Templates
|
||||
|
||||
64
templates/Llama2.hpp
Normal file
64
templates/Llama2.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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 "llmcore/PromptTemplate.hpp"
|
||||
#include <QJsonArray>
|
||||
|
||||
namespace QodeAssist::Templates {
|
||||
|
||||
class Llama2 : public LLMCore::PromptTemplate
|
||||
{
|
||||
public:
|
||||
QString name() const override { return "Llama 2"; }
|
||||
LLMCore::TemplateType type() const override { return LLMCore::TemplateType::Chat; }
|
||||
QString promptTemplate() const override { return {}; }
|
||||
QStringList stopWords() const override { return QStringList() << "[INST]"; }
|
||||
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
||||
{
|
||||
QJsonArray messages = request["messages"].toArray();
|
||||
|
||||
for (int i = 0; i < messages.size(); ++i) {
|
||||
QJsonObject message = messages[i].toObject();
|
||||
QString role = message["role"].toString();
|
||||
QString content = message["content"].toString();
|
||||
|
||||
QString formattedContent;
|
||||
if (role == "system") {
|
||||
formattedContent = QString("[INST]<<SYS>>\n%1\n<</SYS>>[/INST]\n").arg(content);
|
||||
} else if (role == "user") {
|
||||
formattedContent = QString("[INST]%1[/INST]\n").arg(content);
|
||||
} else if (role == "assistant") {
|
||||
formattedContent = content + "\n";
|
||||
}
|
||||
|
||||
message["content"] = formattedContent;
|
||||
messages[i] = message;
|
||||
}
|
||||
|
||||
request["messages"] = messages;
|
||||
}
|
||||
QString description() const override
|
||||
{
|
||||
return "The message will contain the following tokens: [INST]%1[/INST]\n";
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace QodeAssist::Templates
|
||||
@ -20,32 +20,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <QJsonArray>
|
||||
|
||||
#include "llmcore/PromptTemplate.hpp"
|
||||
|
||||
namespace QodeAssist::Templates {
|
||||
|
||||
class StarCoderChat : public LLMCore::PromptTemplate
|
||||
class Llama3 : public LLMCore::PromptTemplate
|
||||
{
|
||||
public:
|
||||
QString name() const override { return "StarCoder Chat"; }
|
||||
QString name() const override { return "Llama 3"; }
|
||||
LLMCore::TemplateType type() const override { return LLMCore::TemplateType::Chat; }
|
||||
QString promptTemplate() const override { return "### Instruction:\n%1\n### Response:\n"; }
|
||||
QString promptTemplate() const override { return ""; }
|
||||
QStringList stopWords() const override
|
||||
{
|
||||
return QStringList() << "###"
|
||||
<< "<|endoftext|>" << "<file_sep>";
|
||||
return QStringList() << "<|start_header_id|>" << "<|end_header_id|>" << "<|eot_id|>";
|
||||
}
|
||||
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
||||
{
|
||||
QString formattedPrompt = promptTemplate().arg(context.prefix);
|
||||
QJsonArray messages = request["messages"].toArray();
|
||||
|
||||
QJsonObject newMessage;
|
||||
newMessage["role"] = "user";
|
||||
newMessage["content"] = formattedPrompt;
|
||||
messages.append(newMessage);
|
||||
for (int i = 0; i < messages.size(); ++i) {
|
||||
QJsonObject message = messages[i].toObject();
|
||||
QString role = message["role"].toString();
|
||||
QString content = message["content"].toString();
|
||||
|
||||
message["content"]
|
||||
= QString("<|start_header_id|>%1<|end_header_id|>%2<|eot_id|>").arg(role, content);
|
||||
|
||||
messages[i] = message;
|
||||
}
|
||||
|
||||
request["messages"] = messages;
|
||||
}
|
||||
QString description() const override
|
||||
{
|
||||
return "The message will contain the following tokens: "
|
||||
"<|start_header_id|>%1<|end_header_id|>%2<|eot_id|>";
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace QodeAssist::Templates
|
||||
65
templates/Ollama.hpp
Normal file
65
templates/Ollama.hpp
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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 <QJsonArray>
|
||||
|
||||
#include "llmcore/PromptTemplate.hpp"
|
||||
|
||||
namespace QodeAssist::Templates {
|
||||
|
||||
class OllamaAutoFim : public LLMCore::PromptTemplate
|
||||
{
|
||||
public:
|
||||
LLMCore::TemplateType type() const override { return LLMCore::TemplateType::Fim; }
|
||||
QString name() const override { return "Ollama Auto FIM"; }
|
||||
QString promptTemplate() const override { return {}; }
|
||||
QStringList stopWords() const override { return QStringList(); }
|
||||
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
||||
{
|
||||
request["prompt"] = context.prefix;
|
||||
request["suffix"] = context.suffix;
|
||||
}
|
||||
QString description() const override { return "template will take from ollama modelfile"; }
|
||||
};
|
||||
|
||||
class OllamaAutoChat : public LLMCore::PromptTemplate
|
||||
{
|
||||
public:
|
||||
LLMCore::TemplateType type() const override { return LLMCore::TemplateType::Chat; }
|
||||
QString name() const override { return "Ollama Auto Chat"; }
|
||||
QString promptTemplate() const override { return {}; }
|
||||
QStringList stopWords() const override { return QStringList(); }
|
||||
|
||||
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
||||
{
|
||||
QJsonArray messages = request["messages"].toArray();
|
||||
|
||||
QJsonObject newMessage;
|
||||
newMessage["role"] = "user";
|
||||
newMessage["content"] = context.prefix;
|
||||
messages.append(newMessage);
|
||||
|
||||
request["messages"] = messages;
|
||||
}
|
||||
QString description() const override { return "template will take from ollama modelfile"; }
|
||||
};
|
||||
|
||||
} // namespace QodeAssist::Templates
|
||||
@ -24,33 +24,6 @@
|
||||
|
||||
namespace QodeAssist::Templates {
|
||||
|
||||
class QwenChat : public LLMCore::PromptTemplate
|
||||
{
|
||||
public:
|
||||
QString name() const override { return "Qwen Chat"; }
|
||||
LLMCore::TemplateType type() const override { return LLMCore::TemplateType::Chat; }
|
||||
|
||||
QString promptTemplate() const override { return "### Instruction:\n%1\n### Response:\n"; }
|
||||
|
||||
QStringList stopWords() const override
|
||||
{
|
||||
return QStringList() << "### Instruction:" << "### Response:" << "\n\n### " << "<|EOT|>";
|
||||
}
|
||||
|
||||
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
||||
{
|
||||
QString formattedPrompt = promptTemplate().arg(context.prefix);
|
||||
QJsonArray messages = request["messages"].toArray();
|
||||
|
||||
QJsonObject newMessage;
|
||||
newMessage["role"] = "user";
|
||||
newMessage["content"] = formattedPrompt;
|
||||
messages.append(newMessage);
|
||||
|
||||
request["messages"] = messages;
|
||||
}
|
||||
};
|
||||
|
||||
class QwenFim : public LLMCore::PromptTemplate
|
||||
{
|
||||
public:
|
||||
@ -66,6 +39,11 @@ public:
|
||||
QString formattedPrompt = promptTemplate().arg(context.prefix, context.suffix);
|
||||
request["prompt"] = formattedPrompt;
|
||||
}
|
||||
QString description() const override
|
||||
{
|
||||
return "The message will contain the following tokens: "
|
||||
"<|fim_prefix|>%1<|fim_suffix|>%2<|fim_middle|>";
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace QodeAssist::Templates
|
||||
|
||||
@ -39,6 +39,11 @@ public:
|
||||
QString formattedPrompt = promptTemplate().arg(context.prefix, context.suffix);
|
||||
request["prompt"] = formattedPrompt;
|
||||
}
|
||||
QString description() const override
|
||||
{
|
||||
return "The message will contain the following tokens: "
|
||||
"<fim_prefix>%1<fim_suffix>%2<fim_middle>";
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace QodeAssist::Templates
|
||||
|
||||
54
templates/Templates.hpp
Normal file
54
templates/Templates.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 "llmcore/PromptTemplateManager.hpp"
|
||||
#include "templates/Alpaca.hpp"
|
||||
#include "templates/BasicChat.hpp"
|
||||
#include "templates/ChatML.hpp"
|
||||
#include "templates/CodeLlamaFim.hpp"
|
||||
#include "templates/CustomFimTemplate.hpp"
|
||||
#include "templates/DeepSeekCoderFim.hpp"
|
||||
#include "templates/Llama2.hpp"
|
||||
#include "templates/Llama3.hpp"
|
||||
#include "templates/Ollama.hpp"
|
||||
#include "templates/Qwen.hpp"
|
||||
#include "templates/StarCoder2Fim.hpp"
|
||||
|
||||
namespace QodeAssist::Templates {
|
||||
|
||||
inline void registerTemplates()
|
||||
{
|
||||
auto &templateManager = LLMCore::PromptTemplateManager::instance();
|
||||
templateManager.registerTemplate<CodeLlamaFim>();
|
||||
templateManager.registerTemplate<StarCoder2Fim>();
|
||||
templateManager.registerTemplate<DeepSeekCoderFim>();
|
||||
templateManager.registerTemplate<CustomTemplate>();
|
||||
templateManager.registerTemplate<QwenFim>();
|
||||
templateManager.registerTemplate<OllamaAutoFim>();
|
||||
templateManager.registerTemplate<OllamaAutoChat>();
|
||||
templateManager.registerTemplate<BasicChat>();
|
||||
templateManager.registerTemplate<Llama3>();
|
||||
templateManager.registerTemplate<ChatML>();
|
||||
templateManager.registerTemplate<Alpaca>();
|
||||
templateManager.registerTemplate<Llama2>();
|
||||
}
|
||||
|
||||
} // namespace QodeAssist::Templates
|
||||
Reference in New Issue
Block a user