Compare commits

...

8 Commits

Author SHA1 Message Date
f41e063c02 chore: Upgrade plugin version to 0.5.4 2025-03-17 02:51:31 +01:00
9d7d084448 fix: Wrong template replace to first template (#143) 2025-03-17 02:48:18 +01:00
1ca1ffc629 fix: Remove reading from replay leading to crash (#142) 2025-03-17 01:22:27 +01:00
8419577ae5 fix: Resolve thread-related QNetworkAccessManager issue (#140)
Fixes "QObject: Cannot create children for a parent that is in a different thread" error by creating QNetworkAccessManager in the same thread where it's used, ensuring proper thread affinity for network operations.
2025-03-16 09:47:04 +01:00
91a6a88130 doc: Add default path for installed plugin 2025-03-14 11:35:37 +01:00
be38abc505 chore: upgrade plugin to 0.5.3 (#139) 2025-03-14 10:59:23 +01:00
f2e0afb6b8 fix: Add qml in code handler for processing model answers (#138) 2025-03-14 10:47:30 +01:00
3cf07238fd doc: Update QtC version to 16 2025-03-14 09:32:54 +01:00
9 changed files with 59 additions and 19 deletions

View File

@ -13,7 +13,7 @@
"Linux" "Linux"
], ],
"license": "GPLv3", "license": "GPLv3",
"version": "0.5.2", "version": "0.5.4",
"status": "draft", "status": "draft",
"is_pack": false, "is_pack": false,
"released_at": null, "released_at": null,
@ -25,8 +25,18 @@
}, },
{ {
"version": "0.5.2", "version": "0.5.2",
"is_latest": true, "is_latest": false,
"released_at": "2025-03-13T17:00:00Z" "released_at": "2025-03-13T17:00:00Z"
},
{
"version": "0.5.3",
"is_latest": false,
"released_at": "2025-03-14T11:00:00Z"
},
{
"version": "0.5.4",
"is_latest": true,
"released_at": "2025-03-17T03:00:00Z"
} }
], ],
"icon": "https://github.com/user-attachments/assets/dc336712-83cb-440d-8761-8d0a31de898d", "icon": "https://github.com/user-attachments/assets/dc336712-83cb-440d-8761-8d0a31de898d",

View File

@ -52,6 +52,7 @@ const QVector<LanguageProperties> &getKnownLanguages()
{"shell", "#", {"shell", "bash", "sh"}, {"sh", "bash"}}, {"shell", "#", {"shell", "bash", "sh"}, {"sh", "bash"}},
{"perl", "#", {"pl", "perl"}, {"pl"}}, {"perl", "#", {"pl", "perl"}, {"pl"}},
{"hs", "--", {"hs", "haskell"}, {"hs"}}, {"hs", "--", {"hs", "haskell"}, {"hs"}},
{"qml", "//", {"qml"}, {"qml"}},
}; };
return knownLanguages; return knownLanguages;

View File

@ -36,6 +36,7 @@ void ConfigurationManager::init()
{ {
setupConnections(); setupConnections();
updateAllTemplateDescriptions(); updateAllTemplateDescriptions();
checkAllTemplate();
} }
void ConfigurationManager::updateTemplateDescription(const Utils::StringAspect &templateAspect) void ConfigurationManager::updateTemplateDescription(const Utils::StringAspect &templateAspect)
@ -59,6 +60,26 @@ void ConfigurationManager::updateAllTemplateDescriptions()
updateTemplateDescription(m_generalSettings.caTemplate); updateTemplateDescription(m_generalSettings.caTemplate);
} }
void ConfigurationManager::checkTemplate(const Utils::StringAspect &templateAspect)
{
LLMCore::PromptTemplate *templ = m_templateManger.getFimTemplateByName(templateAspect.value());
if (templ->name() == templateAspect.value())
return;
if (&templateAspect == &m_generalSettings.ccTemplate) {
m_generalSettings.ccTemplate.setValue(templ->name());
} else if (&templateAspect == &m_generalSettings.caTemplate) {
m_generalSettings.caTemplate.setValue(templ->name());
}
}
void ConfigurationManager::checkAllTemplate()
{
checkTemplate(m_generalSettings.ccTemplate);
checkTemplate(m_generalSettings.caTemplate);
}
ConfigurationManager::ConfigurationManager(QObject *parent) ConfigurationManager::ConfigurationManager(QObject *parent)
: QObject(parent) : QObject(parent)
, m_generalSettings(Settings::generalSettings()) , m_generalSettings(Settings::generalSettings())

View File

@ -38,6 +38,8 @@ public:
void updateTemplateDescription(const Utils::StringAspect &templateAspect); void updateTemplateDescription(const Utils::StringAspect &templateAspect);
void updateAllTemplateDescriptions(); void updateAllTemplateDescriptions();
void checkTemplate(const Utils::StringAspect &templateAspect);
void checkAllTemplate();
public slots: public slots:
void selectProvider(); void selectProvider();

View File

@ -1,13 +1,13 @@
{ {
"Id" : "qodeassist", "Id" : "qodeassist",
"Name" : "QodeAssist", "Name" : "QodeAssist",
"Version" : "0.5.2", "Version" : "0.5.4",
"Vendor" : "Petr Mironychev", "Vendor" : "Petr Mironychev",
"VendorId" : "petrmironychev", "VendorId" : "petrmironychev",
"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",
"License" : "GPLv3", "License" : "GPLv3",
"Description": "QodeAssist is an AI-powered coding assistant for Qt Creator. It provides intelligent code completion and suggestions for your code. Prerequisites: Requires one of the supported LLM providers installed (e.g., Ollama or LM Studio) and a compatible large language model downloaded for your chosen provider (e.g., CodeLlama, StarCoder2).", "Description": "QodeAssist is an AI-powered coding assistant for Qt Creator. It provides intelligent code completion and suggestions for your code. Prerequisites: Requires one of the supported LLM providers installed (e.g., Ollama or LM Studio) and a compatible large language model downloaded for your chosen provider (e.g., CodeLlama, StarCoder2).",
"Url" : "https://github.com/Palm1r/QodeAssist", "Url" : "https://github.com/Palm1r/QodeAssist",
"DocumentationUrl" : "", "DocumentationUrl" : "https://github.com/Palm1r/QodeAssist",
${IDE_PLUGIN_DEPENDENCIES} ${IDE_PLUGIN_DEPENDENCIES}
} }

View File

@ -2,7 +2,7 @@
[![Build plugin](https://github.com/Palm1r/QodeAssist/actions/workflows/build_cmake.yml/badge.svg?branch=main)](https://github.com/Palm1r/QodeAssist/actions/workflows/build_cmake.yml) [![Build plugin](https://github.com/Palm1r/QodeAssist/actions/workflows/build_cmake.yml/badge.svg?branch=main)](https://github.com/Palm1r/QodeAssist/actions/workflows/build_cmake.yml)
![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/Palm1r/QodeAssist/total?color=41%2C173%2C71) ![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/Palm1r/QodeAssist/total?color=41%2C173%2C71)
![GitHub Tag](https://img.shields.io/github/v/tag/Palm1r/QodeAssist) ![GitHub Tag](https://img.shields.io/github/v/tag/Palm1r/QodeAssist)
![Static Badge](https://img.shields.io/badge/QtCreator-15.0.1-brightgreen) ![Static Badge](https://img.shields.io/badge/QtCreator-16.0.0-brightgreen)
[![](https://dcbadge.limes.pink/api/server/BGMkUsXUgf?style=flat)](https://discord.gg/BGMkUsXUgf) [![](https://dcbadge.limes.pink/api/server/BGMkUsXUgf?style=flat)](https://discord.gg/BGMkUsXUgf)
![qodeassist-icon](https://github.com/user-attachments/assets/dc336712-83cb-440d-8761-8d0a31de898d) QodeAssist is an AI-powered coding assistant plugin for Qt Creator. It provides intelligent code completion and suggestions for C++ and QML, leveraging large language models through local providers like Ollama. Enhance your coding productivity with context-aware AI assistance directly in your Qt development environment. ![qodeassist-icon](https://github.com/user-attachments/assets/dc336712-83cb-440d-8761-8d0a31de898d) QodeAssist is an AI-powered coding assistant plugin for Qt Creator. It provides intelligent code completion and suggestions for C++ and QML, leveraging large language models through local providers like Ollama. Enhance your coding productivity with context-aware AI assistance directly in your Qt development environment.
@ -94,6 +94,8 @@ Join our Discord Community: Have questions or want to discuss QodeAssist? Join o
1. Install Latest Qt Creator 1. Install Latest Qt Creator
2. Download the QodeAssist plugin for your Qt Creator 2. Download the QodeAssist plugin for your Qt Creator
- Remove old version plugin if already was installed - Remove old version plugin if already was installed
- on macOS for QtCreator 16: ~/Library/Application Support/QtProject/Qt Creator/plugins/16.0.0/petrmironychev.qodeassist
- on windows for QtCreator 16: C:\Users\<user>\AppData\Local\QtProject\qtcreator\plugins\16.0.0\petrmironychev.qodeassist\lib\qtcreator\plugins
3. Launch Qt Creator and install the plugin: 3. Launch Qt Creator and install the plugin:
- Go to: - Go to:
- MacOS: Qt Creator -> About Plugins... - MacOS: Qt Creator -> About Plugins...
@ -237,7 +239,8 @@ Linked files provide persistent context throughout the conversation:
## QtCreator Version Compatibility ## QtCreator Version Compatibility
- QtCreator 15.0.1 - 0.4.8 - 0.5.x - QtCreator 16.0.0 - 0.5.2 - 0.5.x
- QtCreator 15.0.1 - 0.4.8 - 0.5.1
- QtCreator 15.0.0 - 0.4.0 - 0.4.7 - QtCreator 15.0.0 - 0.4.0 - 0.4.7
- QtCreator 14.0.2 - 0.2.3 - 0.3.x - QtCreator 14.0.2 - 0.2.3 - 0.3.x
- QtCreator 14.0.1 - 0.2.2 plugin version and below - QtCreator 14.0.1 - 0.2.2 plugin version and below

View File

@ -27,7 +27,6 @@ namespace QodeAssist::LLMCore {
RequestHandler::RequestHandler(QObject *parent) RequestHandler::RequestHandler(QObject *parent)
: RequestHandlerBase(parent) : RequestHandlerBase(parent)
, m_manager(new QNetworkAccessManager(this))
{} {}
void RequestHandler::sendLLMRequest(const LLMConfig &config, const QJsonObject &request) void RequestHandler::sendLLMRequest(const LLMConfig &config, const QJsonObject &request)
@ -38,11 +37,12 @@ void RequestHandler::sendLLMRequest(const LLMConfig &config, const QJsonObject &
QString::fromUtf8( QString::fromUtf8(
QJsonDocument(config.providerRequest).toJson(QJsonDocument::Indented)))); QJsonDocument(config.providerRequest).toJson(QJsonDocument::Indented))));
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkRequest networkRequest(config.url); QNetworkRequest networkRequest(config.url);
config.provider->prepareNetworkRequest(networkRequest); config.provider->prepareNetworkRequest(networkRequest);
QNetworkReply *reply QNetworkReply *reply
= m_manager->post(networkRequest, QJsonDocument(config.providerRequest).toJson()); = manager->post(networkRequest, QJsonDocument(config.providerRequest).toJson());
if (!reply) { if (!reply) {
LOG_MESSAGE("Error: Failed to create network reply"); LOG_MESSAGE("Error: Failed to create network reply");
return; return;
@ -55,19 +55,23 @@ void RequestHandler::sendLLMRequest(const LLMConfig &config, const QJsonObject &
handleLLMResponse(reply, request, config); handleLLMResponse(reply, request, config);
}); });
connect(reply, &QNetworkReply::finished, this, [this, reply, requestId]() { connect(reply, &QNetworkReply::finished, this, [this, reply, requestId, manager]() {
reply->deleteLater();
m_activeRequests.remove(requestId); m_activeRequests.remove(requestId);
if (reply->error() != QNetworkReply::NoError) { if (reply->error() != QNetworkReply::NoError) {
LOG_MESSAGE(QString("Error details: %1\nStatus code: %2\nResponse: %3") QString errorMessage = reply->errorString();
.arg(reply->errorString()) int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
.arg(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt())
.arg(QString(reply->readAll()))); LOG_MESSAGE(
emit requestFinished(requestId, false, reply->errorString()); QString("Error details: %1\nStatus code: %2").arg(errorMessage).arg(statusCode));
emit requestFinished(requestId, false, errorMessage);
} else { } else {
LOG_MESSAGE("Request finished successfully"); LOG_MESSAGE("Request finished successfully");
emit requestFinished(requestId, true, QString()); emit requestFinished(requestId, true, QString());
} }
reply->deleteLater();
manager->deleteLater();
}); });
} }

View File

@ -40,7 +40,6 @@ public:
void handleLLMResponse(QNetworkReply *reply, const QJsonObject &request, const LLMConfig &config); void handleLLMResponse(QNetworkReply *reply, const QJsonObject &request, const LLMConfig &config);
private: private:
QNetworkAccessManager *m_manager;
QMap<QString, QNetworkReply *> m_activeRequests; QMap<QString, QNetworkReply *> m_activeRequests;
QMap<QNetworkReply *, QString> m_accumulatedResponses; QMap<QNetworkReply *, QString> m_accumulatedResponses;

View File

@ -94,7 +94,7 @@ GeneralSettings::GeneralSettings()
ccModel.setHistoryCompleter(Constants::CC_MODEL_HISTORY); ccModel.setHistoryCompleter(Constants::CC_MODEL_HISTORY);
ccSelectModel.m_buttonText = TrConstants::SELECT; ccSelectModel.m_buttonText = TrConstants::SELECT;
initStringAspect(ccTemplate, Constants::CC_TEMPLATE, TrConstants::TEMPLATE, "Ollama Auto FIM"); initStringAspect(ccTemplate, Constants::CC_TEMPLATE, TrConstants::TEMPLATE, "Ollama FIM");
ccTemplate.setReadOnly(true); ccTemplate.setReadOnly(true);
ccSelectTemplate.m_buttonText = TrConstants::SELECT; ccSelectTemplate.m_buttonText = TrConstants::SELECT;
@ -140,7 +140,7 @@ GeneralSettings::GeneralSettings()
ccPreset1SelectModel.m_buttonText = TrConstants::SELECT; ccPreset1SelectModel.m_buttonText = TrConstants::SELECT;
initStringAspect( initStringAspect(
ccPreset1Template, Constants::CC_PRESET1_TEMPLATE, TrConstants::TEMPLATE, "Ollama Auto FIM"); ccPreset1Template, Constants::CC_PRESET1_TEMPLATE, TrConstants::TEMPLATE, "Ollama FIM");
ccPreset1Template.setReadOnly(true); ccPreset1Template.setReadOnly(true);
ccPreset1SelectTemplate.m_buttonText = TrConstants::SELECT; ccPreset1SelectTemplate.m_buttonText = TrConstants::SELECT;
@ -153,7 +153,7 @@ GeneralSettings::GeneralSettings()
caModel.setHistoryCompleter(Constants::CA_MODEL_HISTORY); caModel.setHistoryCompleter(Constants::CA_MODEL_HISTORY);
caSelectModel.m_buttonText = TrConstants::SELECT; caSelectModel.m_buttonText = TrConstants::SELECT;
initStringAspect(caTemplate, Constants::CA_TEMPLATE, TrConstants::TEMPLATE, "Ollama Auto Chat"); initStringAspect(caTemplate, Constants::CA_TEMPLATE, TrConstants::TEMPLATE, "Ollama Chat");
caTemplate.setReadOnly(true); caTemplate.setReadOnly(true);
caSelectTemplate.m_buttonText = TrConstants::SELECT; caSelectTemplate.m_buttonText = TrConstants::SELECT;