mirror of
https://github.com/Palm1r/QodeAssist.git
synced 2026-06-15 18:59:13 -04:00
Compare commits
10 Commits
v0.3.9
...
backport-t
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17b0eb8186 | ||
|
|
76c17f03dd | ||
|
|
19c25043fb | ||
|
|
56b5ea8e68 | ||
|
|
b475f15e3d | ||
|
|
31f4516e7b | ||
|
|
bfdbc755e3 | ||
|
|
30964d90d5 | ||
|
|
1261f913bb | ||
|
|
36d5242a1f |
@@ -40,16 +40,22 @@ add_qtc_plugin(QodeAssist
|
|||||||
QodeAssistConstants.hpp
|
QodeAssistConstants.hpp
|
||||||
QodeAssisttr.h
|
QodeAssisttr.h
|
||||||
LLMClientInterface.hpp LLMClientInterface.cpp
|
LLMClientInterface.hpp LLMClientInterface.cpp
|
||||||
|
templates/Templates.hpp
|
||||||
templates/CodeLlamaFim.hpp
|
templates/CodeLlamaFim.hpp
|
||||||
templates/StarCoder2Fim.hpp
|
templates/StarCoder2Fim.hpp
|
||||||
templates/DeepSeekCoderFim.hpp
|
templates/DeepSeekCoderFim.hpp
|
||||||
templates/CustomFimTemplate.hpp
|
templates/CustomFimTemplate.hpp
|
||||||
templates/DeepSeekCoderChat.hpp
|
|
||||||
templates/CodeLlamaChat.hpp
|
|
||||||
templates/Qwen.hpp
|
templates/Qwen.hpp
|
||||||
templates/StarCoderChat.hpp
|
|
||||||
templates/Ollama.hpp
|
templates/Ollama.hpp
|
||||||
templates/BasicChat.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/OllamaProvider.hpp providers/OllamaProvider.cpp
|
||||||
providers/LMStudioProvider.hpp providers/LMStudioProvider.cpp
|
providers/LMStudioProvider.hpp providers/LMStudioProvider.cpp
|
||||||
providers/OpenAICompatProvider.hpp providers/OpenAICompatProvider.cpp
|
providers/OpenAICompatProvider.hpp providers/OpenAICompatProvider.cpp
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ void ClientInterface::sendMessage(const QString &message, bool includeCurrentFil
|
|||||||
{
|
{
|
||||||
cancelRequest();
|
cancelRequest();
|
||||||
|
|
||||||
|
m_chatModel->addMessage(message, ChatModel::ChatRole::User, "");
|
||||||
|
|
||||||
auto &chatAssistantSettings = Settings::chatAssistantSettings();
|
auto &chatAssistantSettings = Settings::chatAssistantSettings();
|
||||||
|
|
||||||
auto providerName = Settings::generalSettings().caProvider();
|
auto providerName = Settings::generalSettings().caProvider();
|
||||||
@@ -124,11 +126,11 @@ void ClientInterface::sendMessage(const QString &message, bool includeCurrentFil
|
|||||||
config.url = QString("%1%2").arg(Settings::generalSettings().caUrl(), provider->chatEndpoint());
|
config.url = QString("%1%2").arg(Settings::generalSettings().caUrl(), provider->chatEndpoint());
|
||||||
config.providerRequest = providerRequest;
|
config.providerRequest = providerRequest;
|
||||||
config.multiLineCompletion = false;
|
config.multiLineCompletion = false;
|
||||||
|
config.apiKey = Settings::chatAssistantSettings().apiKey();
|
||||||
|
|
||||||
QJsonObject request;
|
QJsonObject request;
|
||||||
request["id"] = QUuid::createUuid().toString();
|
request["id"] = QUuid::createUuid().toString();
|
||||||
|
|
||||||
m_chatModel->addMessage(message, ChatModel::ChatRole::User, "");
|
|
||||||
m_requestHandler->sendLLMRequest(config, request);
|
m_requestHandler->sendLLMRequest(config, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,11 +150,16 @@ void ClientInterface::handleLLMResponse(const QString &response,
|
|||||||
const QJsonObject &request,
|
const QJsonObject &request,
|
||||||
bool isComplete)
|
bool isComplete)
|
||||||
{
|
{
|
||||||
|
const auto message = response.trimmed();
|
||||||
|
|
||||||
|
if (!message.isEmpty()) {
|
||||||
QString messageId = request["id"].toString();
|
QString messageId = request["id"].toString();
|
||||||
m_chatModel->addMessage(response.trimmed(), ChatModel::ChatRole::Assistant, messageId);
|
m_chatModel->addMessage(message, ChatModel::ChatRole::Assistant, messageId);
|
||||||
|
|
||||||
if (isComplete) {
|
if (isComplete) {
|
||||||
LOG_MESSAGE("Message completed. Final response for message " + messageId + ": " + response);
|
LOG_MESSAGE(
|
||||||
|
"Message completed. Final response for message " + messageId + ": " + response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -210,10 +210,11 @@ LLMCore::ContextData DocumentContextReader::prepareContext(int lineNumber, int c
|
|||||||
|
|
||||||
QString fileContext;
|
QString fileContext;
|
||||||
if (Settings::codeCompletionSettings().useFilePathInContext())
|
if (Settings::codeCompletionSettings().useFilePathInContext())
|
||||||
fileContext += getLanguageAndFileInfo();
|
fileContext.append("\n ").append(getLanguageAndFileInfo());
|
||||||
|
|
||||||
if (Settings::codeCompletionSettings().useProjectChangesCache())
|
if (Settings::codeCompletionSettings().useProjectChangesCache())
|
||||||
fileContext += ChangesManager::instance().getRecentChangesContext(m_textDocument);
|
fileContext.append("\n ").append(
|
||||||
|
ChangesManager::instance().getRecentChangesContext(m_textDocument));
|
||||||
|
|
||||||
return {contextBefore, contextAfter, fileContext};
|
return {contextBefore, contextAfter, fileContext};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ void LLMClientInterface::handleCompletion(const QJsonObject &request)
|
|||||||
config.promptTemplate = promptTemplate;
|
config.promptTemplate = promptTemplate;
|
||||||
config.url = QUrl(
|
config.url = QUrl(
|
||||||
QString("%1%2").arg(Settings::generalSettings().ccUrl(), provider->completionEndpoint()));
|
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}};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"Name" : "QodeAssist",
|
"Name" : "QodeAssist",
|
||||||
"Version" : "0.3.9",
|
"Version" : "0.3.10",
|
||||||
"CompatVersion" : "${IDE_VERSION_COMPAT}",
|
"CompatVersion" : "${IDE_VERSION_COMPAT}",
|
||||||
"Vendor" : "Petr Mironychev",
|
"Vendor" : "Petr Mironychev",
|
||||||
"Copyright" : "(C) ${IDE_COPYRIGHT_YEAR} Petr Mironychev, (C) ${IDE_COPYRIGHT_YEAR} The Qt Company Ltd",
|
"Copyright" : "(C) ${IDE_COPYRIGHT_YEAR} Petr Mironychev, (C) ${IDE_COPYRIGHT_YEAR} The Qt Company Ltd",
|
||||||
|
|||||||
26
README.md
26
README.md
@@ -29,8 +29,8 @@ QodeAssist is an AI-powered coding assistant plugin for Qt Creator. It provides
|
|||||||
- Side and Bottom panels
|
- Side and Bottom panels
|
||||||
- Support for multiple LLM providers:
|
- Support for multiple LLM providers:
|
||||||
- Ollama
|
- Ollama
|
||||||
- LM Studio (experimental)
|
- LM Studio
|
||||||
- OpenAI-compatible providers (experimental)
|
- OpenAI-compatible providers(eg. https://openrouter.ai)
|
||||||
- Extensive library of model-specific templates
|
- Extensive library of model-specific templates
|
||||||
- Custom template support
|
- Custom template support
|
||||||
- Easy configuration and model selection
|
- Easy configuration and model selection
|
||||||
@@ -120,6 +120,28 @@ ollama run qwen2.5-coder:7b-instruct
|
|||||||
ollama run deepseek-coder-v2
|
ollama run deepseek-coder-v2
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Template-Model Compatibility
|
||||||
|
|
||||||
|
| Template | Compatible Models | Purpose |
|
||||||
|
|----------|------------------|----------|
|
||||||
|
| CodeLlama FIM | `codellama:code` | Code completion |
|
||||||
|
| DeepSeekCoder FIM | `deepseek-coder-v2`, `deepseek-v2.5` | Code completion |
|
||||||
|
| Ollama Auto FIM | `Any Ollama base model` | Code completion |
|
||||||
|
| Qwen FIM | `Qwen 2.5 models` | Code completion |
|
||||||
|
| StarCoder2 FIM | `starcoder2 base model` | Code completion |
|
||||||
|
| Alpaca | `starcoder2:instruct` | Chat assistance |
|
||||||
|
| Basic Chat| `Messages without tokens` | Chat assistance |
|
||||||
|
| ChatML | `Qwen 2.5 models` | Chat assistance |
|
||||||
|
| Llama2 | `llama2 model family`, `codellama:instruct` | Chat assistance |
|
||||||
|
| Llama3 | `llama3 model family` | Chat assistance |
|
||||||
|
| Ollama Auto Chat | `Any Ollama chat model` | Chat assistance |
|
||||||
|
|
||||||
|
> Note:
|
||||||
|
> - FIM (Fill-in-Middle) templates are optimized for code completion
|
||||||
|
> - Chat templates are designed for interactive dialogue
|
||||||
|
> - The Ollama Auto templates automatically adapt to most Ollama models
|
||||||
|
> - Custom Template allows you to define your own prompt format
|
||||||
|
|
||||||
## QtCreator Version Compatibility
|
## QtCreator Version Compatibility
|
||||||
|
|
||||||
- QtCreator 14.0.2 - 0.2.3 - 0.3.x
|
- QtCreator 14.0.2 - 0.2.3 - 0.3.x
|
||||||
|
|||||||
@@ -38,5 +38,6 @@ public:
|
|||||||
virtual QString promptTemplate() const = 0;
|
virtual QString promptTemplate() const = 0;
|
||||||
virtual QStringList stopWords() const = 0;
|
virtual QStringList stopWords() const = 0;
|
||||||
virtual void prepareRequest(QJsonObject &request, const ContextData &context) const = 0;
|
virtual void prepareRequest(QJsonObject &request, const ContextData &context) const = 0;
|
||||||
|
virtual QString description() const = 0;
|
||||||
};
|
};
|
||||||
} // namespace QodeAssist::LLMCore
|
} // namespace QodeAssist::LLMCore
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ struct LLMConfig
|
|||||||
QJsonObject providerRequest;
|
QJsonObject providerRequest;
|
||||||
RequestType requestType;
|
RequestType requestType;
|
||||||
bool multiLineCompletion;
|
bool multiLineCompletion;
|
||||||
|
QString apiKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QodeAssist::LLMCore
|
} // namespace QodeAssist::LLMCore
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ void RequestHandler::sendLLMRequest(const LLMConfig &config, const QJsonObject &
|
|||||||
QJsonDocument(config.providerRequest).toJson(QJsonDocument::Indented))));
|
QJsonDocument(config.providerRequest).toJson(QJsonDocument::Indented))));
|
||||||
|
|
||||||
QNetworkRequest networkRequest(config.url);
|
QNetworkRequest networkRequest(config.url);
|
||||||
prepareNetworkRequest(networkRequest, config.providerRequest);
|
prepareNetworkRequest(networkRequest, config.apiKey);
|
||||||
|
|
||||||
QNetworkReply *reply = m_manager->post(networkRequest,
|
QNetworkReply *reply = m_manager->post(networkRequest,
|
||||||
QJsonDocument(config.providerRequest).toJson());
|
QJsonDocument(config.providerRequest).toJson());
|
||||||
@@ -84,6 +84,8 @@ void RequestHandler::handleLLMResponse(QNetworkReply *reply,
|
|||||||
if (isComplete) {
|
if (isComplete) {
|
||||||
auto cleanedCompletion = removeStopWords(accumulatedResponse,
|
auto cleanedCompletion = removeStopWords(accumulatedResponse,
|
||||||
config.promptTemplate->stopWords());
|
config.promptTemplate->stopWords());
|
||||||
|
removeCodeBlockWrappers(cleanedCompletion);
|
||||||
|
|
||||||
emit completionReceived(cleanedCompletion, request, true);
|
emit completionReceived(cleanedCompletion, request, true);
|
||||||
}
|
}
|
||||||
} else if (config.requestType == RequestType::Chat) {
|
} else if (config.requestType == RequestType::Chat) {
|
||||||
@@ -107,33 +109,33 @@ bool RequestHandler::cancelRequest(const QString &id)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RequestHandler::prepareNetworkRequest(QNetworkRequest &networkRequest,
|
void RequestHandler::prepareNetworkRequest(
|
||||||
const QJsonObject &providerRequest)
|
QNetworkRequest &networkRequest, const QString &apiKey) const
|
||||||
{
|
{
|
||||||
networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||||
|
|
||||||
if (providerRequest.contains("api_key")) {
|
if (!apiKey.isEmpty()) {
|
||||||
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,
|
bool RequestHandler::processSingleLineCompletion(
|
||||||
|
QNetworkReply *reply,
|
||||||
const QJsonObject &request,
|
const QJsonObject &request,
|
||||||
const QString &accumulatedResponse,
|
const QString &accumulatedResponse,
|
||||||
const LLMConfig &config)
|
const LLMConfig &config)
|
||||||
{
|
{
|
||||||
int newlinePos = accumulatedResponse.indexOf('\n');
|
QString cleanedResponse = accumulatedResponse;
|
||||||
|
removeCodeBlockWrappers(cleanedResponse);
|
||||||
|
|
||||||
|
int newlinePos = cleanedResponse.indexOf('\n');
|
||||||
if (newlinePos != -1) {
|
if (newlinePos != -1) {
|
||||||
QString singleLineCompletion = accumulatedResponse.left(newlinePos).trimmed();
|
QString singleLineCompletion = cleanedResponse.left(newlinePos).trimmed();
|
||||||
singleLineCompletion = removeStopWords(singleLineCompletion,
|
singleLineCompletion
|
||||||
config.promptTemplate->stopWords());
|
= removeStopWords(singleLineCompletion, config.promptTemplate->stopWords());
|
||||||
|
|
||||||
emit completionReceived(singleLineCompletion, request, true);
|
emit completionReceived(singleLineCompletion, request, true);
|
||||||
m_accumulatedResponses.remove(reply);
|
m_accumulatedResponses.remove(reply);
|
||||||
reply->abort();
|
reply->abort();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -150,4 +152,36 @@ QString RequestHandler::removeStopWords(const QStringView &completion, const QSt
|
|||||||
return filteredCompletion;
|
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
|
} // namespace QodeAssist::LLMCore
|
||||||
|
|||||||
@@ -52,12 +52,13 @@ private:
|
|||||||
QMap<QString, QNetworkReply *> m_activeRequests;
|
QMap<QString, QNetworkReply *> m_activeRequests;
|
||||||
QMap<QNetworkReply *, QString> m_accumulatedResponses;
|
QMap<QNetworkReply *, QString> m_accumulatedResponses;
|
||||||
|
|
||||||
void prepareNetworkRequest(QNetworkRequest &networkRequest, const QJsonObject &providerRequest);
|
void prepareNetworkRequest(QNetworkRequest &networkRequest, const QString &apiKey) const;
|
||||||
bool processSingleLineCompletion(QNetworkReply *reply,
|
bool processSingleLineCompletion(QNetworkReply *reply,
|
||||||
const QJsonObject &request,
|
const QJsonObject &request,
|
||||||
const QString &accumulatedResponse,
|
const QString &accumulatedResponse,
|
||||||
const LLMConfig &config);
|
const LLMConfig &config);
|
||||||
QString removeStopWords(const QStringView &completion, const QStringList &stopWords);
|
QString removeStopWords(const QStringView &completion, const QStringList &stopWords);
|
||||||
|
void removeCodeBlockWrappers(QString &response);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QodeAssist::LLMCore
|
} // namespace QodeAssist::LLMCore
|
||||||
|
|||||||
@@ -26,13 +26,15 @@
|
|||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
|
|
||||||
|
#include "logger/Logger.hpp"
|
||||||
|
|
||||||
namespace QodeAssist::Providers {
|
namespace QodeAssist::Providers {
|
||||||
|
|
||||||
OpenAICompatProvider::OpenAICompatProvider() {}
|
OpenAICompatProvider::OpenAICompatProvider() {}
|
||||||
|
|
||||||
QString OpenAICompatProvider::name() const
|
QString OpenAICompatProvider::name() const
|
||||||
{
|
{
|
||||||
return "OpenAI Compatible (experimental)";
|
return "OpenAI Compatible";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString OpenAICompatProvider::url() const
|
QString OpenAICompatProvider::url() const
|
||||||
@@ -82,10 +84,6 @@ void OpenAICompatProvider::prepareRequest(QJsonObject &request, LLMCore::Request
|
|||||||
request["frequency_penalty"] = settings.frequencyPenalty();
|
request["frequency_penalty"] = settings.frequencyPenalty();
|
||||||
if (settings.usePresencePenalty())
|
if (settings.usePresencePenalty())
|
||||||
request["presence_penalty"] = settings.presencePenalty();
|
request["presence_penalty"] = settings.presencePenalty();
|
||||||
const QString &apiKey = settings.apiKey();
|
|
||||||
if (!apiKey.isEmpty()) {
|
|
||||||
request["api_key"] = apiKey;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QJsonArray messages = prepareMessages(request);
|
QJsonArray messages = prepareMessages(request);
|
||||||
@@ -103,24 +101,41 @@ void OpenAICompatProvider::prepareRequest(QJsonObject &request, LLMCore::Request
|
|||||||
bool OpenAICompatProvider::handleResponse(QNetworkReply *reply, QString &accumulatedResponse)
|
bool OpenAICompatProvider::handleResponse(QNetworkReply *reply, QString &accumulatedResponse)
|
||||||
{
|
{
|
||||||
bool isComplete = false;
|
bool isComplete = false;
|
||||||
|
QString tempResponse = accumulatedResponse;
|
||||||
|
|
||||||
while (reply->canReadLine()) {
|
while (reply->canReadLine()) {
|
||||||
QByteArray line = reply->readLine().trimmed();
|
QByteArray line = reply->readLine().trimmed();
|
||||||
if (line.isEmpty()) {
|
if (line.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (line == "data: [DONE]") {
|
|
||||||
|
if (!line.startsWith("data:")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
line = line.mid(6);
|
||||||
|
|
||||||
|
if (line == "[DONE]") {
|
||||||
isComplete = true;
|
isComplete = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (line.startsWith("data: ")) {
|
|
||||||
line = line.mid(6); // Remove "data: " prefix
|
|
||||||
}
|
|
||||||
QJsonDocument jsonResponse = QJsonDocument::fromJson(line);
|
QJsonDocument jsonResponse = QJsonDocument::fromJson(line);
|
||||||
if (jsonResponse.isNull()) {
|
if (jsonResponse.isNull()) {
|
||||||
qWarning() << "Invalid JSON response from LM Studio:" << line;
|
LOG_MESSAGE(
|
||||||
|
"Invalid JSON response from OpenAI compatible provider: " + QString::fromUtf8(line));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject responseObj = jsonResponse.object();
|
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")) {
|
if (responseObj.contains("choices")) {
|
||||||
QJsonArray choices = responseObj["choices"].toArray();
|
QJsonArray choices = responseObj["choices"].toArray();
|
||||||
if (!choices.isEmpty()) {
|
if (!choices.isEmpty()) {
|
||||||
@@ -128,16 +143,30 @@ bool OpenAICompatProvider::handleResponse(QNetworkReply *reply, QString &accumul
|
|||||||
QJsonObject delta = choice["delta"].toObject();
|
QJsonObject delta = choice["delta"].toObject();
|
||||||
if (delta.contains("content")) {
|
if (delta.contains("content")) {
|
||||||
QString completion = delta["content"].toString();
|
QString completion = delta["content"].toString();
|
||||||
|
if (!completion.isEmpty()) {
|
||||||
accumulatedResponse += completion;
|
tempResponse += completion;
|
||||||
}
|
}
|
||||||
if (choice["finish_reason"].toString() == "stop") {
|
}
|
||||||
|
QString finishReason = choice["finish_reason"].toString();
|
||||||
|
if (!finishReason.isNull() && finishReason == "stop") {
|
||||||
isComplete = true;
|
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;
|
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,22 +43,9 @@
|
|||||||
#include "QodeAssistClient.hpp"
|
#include "QodeAssistClient.hpp"
|
||||||
#include "chat/ChatOutputPane.h"
|
#include "chat/ChatOutputPane.h"
|
||||||
#include "chat/NavigationPanel.hpp"
|
#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/BasicChat.hpp"
|
#include "providers/Providers.hpp"
|
||||||
#include "templates/CodeLlamaChat.hpp"
|
#include "templates/Templates.hpp"
|
||||||
#include "templates/CodeLlamaFim.hpp"
|
|
||||||
#include "templates/CustomFimTemplate.hpp"
|
|
||||||
#include "templates/DeepSeekCoderChat.hpp"
|
|
||||||
#include "templates/DeepSeekCoderFim.hpp"
|
|
||||||
#include "templates/Ollama.hpp"
|
|
||||||
#include "templates/Qwen.hpp"
|
|
||||||
#include "templates/StarCoder2Fim.hpp"
|
|
||||||
#include "templates/StarCoderChat.hpp"
|
|
||||||
|
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
@@ -85,25 +72,8 @@ public:
|
|||||||
|
|
||||||
void initialize() final
|
void initialize() final
|
||||||
{
|
{
|
||||||
auto &providerManager = LLMCore::ProvidersManager::instance();
|
Providers::registerProviders();
|
||||||
providerManager.registerProvider<Providers::OllamaProvider>();
|
Templates::registerTemplates();
|
||||||
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>();
|
|
||||||
templateManager.registerTemplate<Templates::OllamaAutoFim>();
|
|
||||||
templateManager.registerTemplate<Templates::OllamaAutoChat>();
|
|
||||||
templateManager.registerTemplate<Templates::BasicChat>();
|
|
||||||
|
|
||||||
Utils::Icon QCODEASSIST_ICON(
|
Utils::Icon QCODEASSIST_ICON(
|
||||||
{{":/resources/images/qoderassist-icon.png", Utils::Theme::IconsBaseColor}});
|
{{":/resources/images/qoderassist-icon.png", Utils::Theme::IconsBaseColor}});
|
||||||
|
|||||||
@@ -143,9 +143,8 @@ CodeCompletionSettings::CodeCompletionSettings()
|
|||||||
|
|
||||||
systemPrompt.setSettingsKey(Constants::CC_SYSTEM_PROMPT);
|
systemPrompt.setSettingsKey(Constants::CC_SYSTEM_PROMPT);
|
||||||
systemPrompt.setDisplayStyle(Utils::StringAspect::TextEditDisplay);
|
systemPrompt.setDisplayStyle(Utils::StringAspect::TextEditDisplay);
|
||||||
systemPrompt.setDefaultValue(
|
systemPrompt.setDefaultValue("You are an expert C++, Qt, and QML code completion AI. ANSWER "
|
||||||
"You are an expert C++, Qt, and QML code completion AI. Your task is to provide accurate "
|
"should be SHORT and in CODE");
|
||||||
"and contextually appropriate code suggestions.");
|
|
||||||
|
|
||||||
useFilePathInContext.setSettingsKey(Constants::CC_USE_FILE_PATH_IN_CONTEXT);
|
useFilePathInContext.setSettingsKey(Constants::CC_USE_FILE_PATH_IN_CONTEXT);
|
||||||
useFilePathInContext.setDefaultValue(true);
|
useFilePathInContext.setDefaultValue(true);
|
||||||
|
|||||||
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
|
||||||
@@ -32,18 +32,9 @@ public:
|
|||||||
QString name() const override { return "Basic Chat"; }
|
QString name() const override { return "Basic Chat"; }
|
||||||
QString promptTemplate() const override { return {}; }
|
QString promptTemplate() const override { return {}; }
|
||||||
QStringList stopWords() const override { return QStringList(); }
|
QStringList stopWords() const override { return QStringList(); }
|
||||||
|
|
||||||
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
||||||
{
|
{}
|
||||||
QJsonArray messages = request["messages"].toArray();
|
QString description() const override { return "chat without tokens"; }
|
||||||
|
|
||||||
QJsonObject newMessage;
|
|
||||||
newMessage["role"] = "user";
|
|
||||||
newMessage["content"] = context.prefix;
|
|
||||||
messages.append(newMessage);
|
|
||||||
|
|
||||||
request["messages"] = messages;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QodeAssist::Templates
|
} // namespace QodeAssist::Templates
|
||||||
|
|||||||
@@ -20,35 +20,41 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
|
||||||
#include "llmcore/PromptTemplate.hpp"
|
#include "llmcore/PromptTemplate.hpp"
|
||||||
|
|
||||||
namespace QodeAssist::Templates {
|
namespace QodeAssist::Templates {
|
||||||
|
|
||||||
class DeepSeekCoderChat : public LLMCore::PromptTemplate
|
class ChatML : public LLMCore::PromptTemplate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QString name() const override { return "DeepSeekCoder Chat"; }
|
QString name() const override { return "ChatML"; }
|
||||||
LLMCore::TemplateType type() const override { return LLMCore::TemplateType::Chat; }
|
LLMCore::TemplateType type() const override { return LLMCore::TemplateType::Chat; }
|
||||||
|
QString promptTemplate() const override { return {}; }
|
||||||
QString promptTemplate() const override { return "### Instruction:\n%1\n### Response:\n"; }
|
|
||||||
|
|
||||||
QStringList stopWords() const override
|
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
|
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
||||||
{
|
{
|
||||||
QString formattedPrompt = promptTemplate().arg(context.prefix);
|
|
||||||
QJsonArray messages = request["messages"].toArray();
|
QJsonArray messages = request["messages"].toArray();
|
||||||
|
|
||||||
QJsonObject newMessage;
|
for (int i = 0; i < messages.size(); ++i) {
|
||||||
newMessage["role"] = "user";
|
QJsonObject message = messages[i].toObject();
|
||||||
newMessage["content"] = formattedPrompt;
|
QString role = message["role"].toString();
|
||||||
messages.append(newMessage);
|
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;
|
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
|
} // namespace QodeAssist::Templates
|
||||||
@@ -33,12 +33,15 @@ public:
|
|||||||
{
|
{
|
||||||
return QStringList() << "<EOT>" << "<PRE>" << "<SUF" << "<MID>";
|
return QStringList() << "<EOT>" << "<PRE>" << "<SUF" << "<MID>";
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
||||||
{
|
{
|
||||||
QString formattedPrompt = promptTemplate().arg(context.prefix, context.suffix);
|
QString formattedPrompt = promptTemplate().arg(context.prefix, context.suffix);
|
||||||
request["prompt"] = formattedPrompt;
|
request["prompt"] = formattedPrompt;
|
||||||
}
|
}
|
||||||
|
QString description() const override
|
||||||
|
{
|
||||||
|
return "The message will contain the following tokens: <PRE> %1 <SUF>%2 <MID>";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QodeAssist::Templates
|
} // namespace QodeAssist::Templates
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ public:
|
|||||||
return Settings::customPromptSettings().customJsonTemplate();
|
return Settings::customPromptSettings().customJsonTemplate();
|
||||||
}
|
}
|
||||||
QStringList stopWords() const override { return QStringList(); }
|
QStringList stopWords() const override { return QStringList(); }
|
||||||
|
|
||||||
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
||||||
{
|
{
|
||||||
QJsonDocument doc = QJsonDocument::fromJson(promptTemplate().toUtf8());
|
QJsonDocument doc = QJsonDocument::fromJson(promptTemplate().toUtf8());
|
||||||
@@ -56,6 +55,7 @@ public:
|
|||||||
request[it.key()] = it.value();
|
request[it.key()] = it.value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
QString description() const override { return promptTemplate(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QJsonValue processJsonValue(const QJsonValue &value, const LLMCore::ContextData &context) const
|
QJsonValue processJsonValue(const QJsonValue &value, const LLMCore::ContextData &context) const
|
||||||
|
|||||||
@@ -38,6 +38,11 @@ public:
|
|||||||
QString formattedPrompt = promptTemplate().arg(context.prefix, context.suffix);
|
QString formattedPrompt = promptTemplate().arg(context.prefix, context.suffix);
|
||||||
request["prompt"] = formattedPrompt;
|
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
|
} // namespace QodeAssist::Templates
|
||||||
|
|||||||
@@ -19,38 +19,46 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QJsonArray>
|
|
||||||
|
|
||||||
#include "llmcore/PromptTemplate.hpp"
|
#include "llmcore/PromptTemplate.hpp"
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
namespace QodeAssist::Templates {
|
namespace QodeAssist::Templates {
|
||||||
|
|
||||||
class CodeLlamaChat : public LLMCore::PromptTemplate
|
class Llama2 : public LLMCore::PromptTemplate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
QString name() const override { return "Llama 2"; }
|
||||||
LLMCore::TemplateType type() const override { return LLMCore::TemplateType::Chat; }
|
LLMCore::TemplateType type() const override { return LLMCore::TemplateType::Chat; }
|
||||||
QString name() const override { return "CodeLlama Chat"; }
|
QString promptTemplate() const override { return {}; }
|
||||||
QString promptTemplate() const override { return "[INST] %1 [/INST]"; }
|
QStringList stopWords() const override { return QStringList() << "[INST]"; }
|
||||||
QStringList stopWords() const override { return QStringList() << "[INST]" << "[/INST]"; }
|
|
||||||
|
|
||||||
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
||||||
{
|
{
|
||||||
QString formattedPrompt = promptTemplate().arg(context.prefix);
|
|
||||||
QJsonArray messages = request["messages"].toArray();
|
QJsonArray messages = request["messages"].toArray();
|
||||||
|
|
||||||
QJsonObject newMessage;
|
for (int i = 0; i < messages.size(); ++i) {
|
||||||
newMessage["role"] = "user";
|
QJsonObject message = messages[i].toObject();
|
||||||
newMessage["content"] = formattedPrompt;
|
QString role = message["role"].toString();
|
||||||
messages.append(newMessage);
|
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;
|
request["messages"] = messages;
|
||||||
}
|
}
|
||||||
};
|
QString description() const override
|
||||||
|
{
|
||||||
class LlamaChat : public CodeLlamaChat
|
return "The message will contain the following tokens: [INST]%1[/INST]\n";
|
||||||
{
|
}
|
||||||
public:
|
|
||||||
QString name() const override { return "Llama Chat"; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QodeAssist::Templates
|
} // namespace QodeAssist::Templates
|
||||||
@@ -20,32 +20,43 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
|
||||||
#include "llmcore/PromptTemplate.hpp"
|
#include "llmcore/PromptTemplate.hpp"
|
||||||
|
|
||||||
namespace QodeAssist::Templates {
|
namespace QodeAssist::Templates {
|
||||||
|
|
||||||
class StarCoderChat : public LLMCore::PromptTemplate
|
class Llama3 : public LLMCore::PromptTemplate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QString name() const override { return "StarCoder Chat"; }
|
QString name() const override { return "Llama 3"; }
|
||||||
LLMCore::TemplateType type() const override { return LLMCore::TemplateType::Chat; }
|
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
|
QStringList stopWords() const override
|
||||||
{
|
{
|
||||||
return QStringList() << "###"
|
return QStringList() << "<|start_header_id|>" << "<|end_header_id|>" << "<|eot_id|>";
|
||||||
<< "<|endoftext|>" << "<file_sep>";
|
|
||||||
}
|
}
|
||||||
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
||||||
{
|
{
|
||||||
QString formattedPrompt = promptTemplate().arg(context.prefix);
|
|
||||||
QJsonArray messages = request["messages"].toArray();
|
QJsonArray messages = request["messages"].toArray();
|
||||||
|
|
||||||
QJsonObject newMessage;
|
for (int i = 0; i < messages.size(); ++i) {
|
||||||
newMessage["role"] = "user";
|
QJsonObject message = messages[i].toObject();
|
||||||
newMessage["content"] = formattedPrompt;
|
QString role = message["role"].toString();
|
||||||
messages.append(newMessage);
|
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;
|
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
|
} // namespace QodeAssist::Templates
|
||||||
@@ -32,12 +32,12 @@ public:
|
|||||||
QString name() const override { return "Ollama Auto FIM"; }
|
QString name() const override { return "Ollama Auto FIM"; }
|
||||||
QString promptTemplate() const override { return {}; }
|
QString promptTemplate() const override { return {}; }
|
||||||
QStringList stopWords() const override { return QStringList(); }
|
QStringList stopWords() const override { return QStringList(); }
|
||||||
|
|
||||||
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
void prepareRequest(QJsonObject &request, const LLMCore::ContextData &context) const override
|
||||||
{
|
{
|
||||||
request["prompt"] = context.prefix;
|
request["prompt"] = context.prefix;
|
||||||
request["suffix"] = context.suffix;
|
request["suffix"] = context.suffix;
|
||||||
}
|
}
|
||||||
|
QString description() const override { return "template will take from ollama modelfile"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class OllamaAutoChat : public LLMCore::PromptTemplate
|
class OllamaAutoChat : public LLMCore::PromptTemplate
|
||||||
@@ -59,6 +59,7 @@ public:
|
|||||||
|
|
||||||
request["messages"] = messages;
|
request["messages"] = messages;
|
||||||
}
|
}
|
||||||
|
QString description() const override { return "template will take from ollama modelfile"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QodeAssist::Templates
|
} // namespace QodeAssist::Templates
|
||||||
|
|||||||
@@ -24,33 +24,6 @@
|
|||||||
|
|
||||||
namespace QodeAssist::Templates {
|
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
|
class QwenFim : public LLMCore::PromptTemplate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -66,6 +39,11 @@ public:
|
|||||||
QString formattedPrompt = promptTemplate().arg(context.prefix, context.suffix);
|
QString formattedPrompt = promptTemplate().arg(context.prefix, context.suffix);
|
||||||
request["prompt"] = formattedPrompt;
|
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
|
} // namespace QodeAssist::Templates
|
||||||
|
|||||||
@@ -39,6 +39,11 @@ public:
|
|||||||
QString formattedPrompt = promptTemplate().arg(context.prefix, context.suffix);
|
QString formattedPrompt = promptTemplate().arg(context.prefix, context.suffix);
|
||||||
request["prompt"] = formattedPrompt;
|
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
|
} // 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