Move to get models by request to provider

This commit is contained in:
Petr Mironychev 2024-09-01 18:19:37 +02:00
parent 6703a7026d
commit a974b0aa82
7 changed files with 48 additions and 102 deletions

View File

@ -1,6 +1,6 @@
{
"Name" : "QodeAssist",
"Version" : "0.0.7",
"Version" : "0.0.8",
"CompatVersion" : "${IDE_VERSION_COMPAT}",
"Vendor" : "Petr Mironychev",
"Copyright" : "(C) ${IDE_COPYRIGHT_YEAR} Petr Mironychev, (C) ${IDE_COPYRIGHT_YEAR} The Qt Company Ltd",

View File

@ -77,7 +77,7 @@ QodeAssistSettings::QodeAssistSettings()
temperature.setDefaultValue(0.2);
temperature.setRange(0.0, 10.0);
selectModels.m_buttonText = Tr::tr("Select Models");
selectModels.m_buttonText = Tr::tr("Select Model");
ollamaLivetime.setSettingsKey(Constants::OLLAMA_LIVETIME);
ollamaLivetime.setLabelText(
@ -145,9 +145,6 @@ QodeAssistSettings::QodeAssistSettings()
frequencyPenalty.setDefaultValue(0.0);
frequencyPenalty.setRange(-2.0, 2.0);
providerPaths.setSettingsKey(Constants::PROVIDER_PATHS);
providerPaths.setLabelText(Tr::tr("Provider Paths:"));
startSuggestionTimer.setSettingsKey(Constants::START_SUGGESTION_TIMER);
startSuggestionTimer.setLabelText(Tr::tr("Start Suggestion Timer:"));
startSuggestionTimer.setRange(10, 10000);
@ -219,7 +216,7 @@ QodeAssistSettings::QodeAssistSettings()
enableLogging,
Row{Stretch{1}, resetToDefaults}}}},
Group{title(Tr::tr("LLM Providers")),
Form{Column{llmProviders, Row{url, endPoint}, providerPaths}}},
Form{Column{llmProviders, Row{url, endPoint}}}},
Group{title(Tr::tr("LLM Model Settings")),
Form{Column{Row{selectModels, modelName}}}},
Group{title(Tr::tr("FIM Prompt Settings")),
@ -306,7 +303,7 @@ QStringList QodeAssistSettings::getInstalledModels()
{
auto *provider = LLMProvidersManager::instance().getCurrentProvider();
if (provider) {
auto env = getEnvironmentWithProviderPaths();
Utils::Environment env = Utils::Environment::systemEnvironment();
return provider->getInstalledModels(env);
}
return {};
@ -331,16 +328,6 @@ void QodeAssistSettings::showModelSelectionDialog()
}
}
Utils::Environment QodeAssistSettings::getEnvironmentWithProviderPaths() const
{
Utils::Environment env = Utils::Environment::systemEnvironment();
const QStringList additionalPaths = providerPaths.volatileValue();
for (const QString &path : additionalPaths) {
env.prependOrSetPath(path);
}
return env;
}
void QodeAssistSettings::resetSettingsToDefaults()
{
QMessageBox::StandardButton reply;

View File

@ -88,8 +88,6 @@ public:
Utils::BoolAspect useFrequencyPenalty{this};
Utils::DoubleAspect frequencyPenalty{this};
Utils::StringListAspect providerPaths{this};
Utils::IntegerAspect startSuggestionTimer{this};
Utils::IntegerAspect maxFileThreshold{this};

View File

@ -15,6 +15,7 @@ QodeAssist has been tested with the following language models, all trained for F
Ollama:
- [starcoder2](https://ollama.com/library/starcoder2)
- [codellama](https://ollama.com/library/codellama)
- DeepSeek-Coder-V2-Lite-Base
LM studio:
- [second-state/StarCoder2-7B-GGUF](https://huggingface.co/second-state/StarCoder2-7B-GGUF)
@ -30,7 +31,7 @@ If you've successfully used a model that's not listed here, please let us know b
- [ ] Add chat functionality
- [ ] Support for more providers and models
## Installation Plugin
## Plugin installation using Ollama as an example
1. Install QtCreator 14.0
2. Install [Ollama](https://ollama.com). Make sure to review the system requirements before installation.
@ -50,9 +51,8 @@ ollama run starcoder2:7b
1. Open Qt Creator settings
2. Navigate to the "Qode Assist" tab
3. Choose your LLM provider (e.g., Ollama)
- If you haven't added the provider to your system PATH, specify the path to the provider executable in the "Provider Paths" field
4. Select the installed model
- If you need to enter the model name manually, it indicates that the plugin cannot locate the provider's executable file. However, this doesn't affect the plugin's functionality it will still work correctly. This autoselector input option is provided for your convenience, allowing you to easily select and use different models
4. Select the installed model by the "Select Model" button
- For LM Studio you will see current load model
5. Choose the prompt template that corresponds to your model
6. Apply the settings

View File

@ -19,14 +19,15 @@
#include "LMStudioProvider.hpp"
#include <QEventLoop>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QNetworkReply>
#include <QProcess>
#include "PromptTemplateManager.hpp"
#include "QodeAssistSettings.hpp"
#include "QodeAssistUtils.hpp"
namespace QodeAssist::Providers {
@ -113,53 +114,32 @@ bool LMStudioProvider::handleResponse(QNetworkReply *reply, QString &accumulated
QList<QString> LMStudioProvider::getInstalledModels(const Utils::Environment &env)
{
QProcess process;
process.setEnvironment(env.toStringList());
QString lmsConsoleName;
#ifdef Q_OS_WIN
lmsConsoleName = "lms.exe";
#else
lmsConsoleName = "lms";
#endif
auto lmsPath = env.searchInPath(lmsConsoleName).toString();
QList<QString> models;
QNetworkAccessManager manager;
QNetworkRequest request(QUrl(url() + "/v1/models"));
if (!QFileInfo::exists(lmsPath)) {
qWarning() << "LMS executable not found at" << lmsPath;
return {};
}
QNetworkReply *reply = manager.get(request);
process.start(lmsPath, QStringList() << "ls");
if (!process.waitForStarted()) {
qWarning() << "Failed to start LMS process:" << process.errorString();
return {};
}
QEventLoop loop;
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec();
if (!process.waitForFinished()) {
qWarning() << "LMS process did not finish:" << process.errorString();
return {};
}
if (reply->error() == QNetworkReply::NoError) {
QByteArray responseData = reply->readAll();
QJsonDocument jsonResponse = QJsonDocument::fromJson(responseData);
QJsonObject jsonObject = jsonResponse.object();
QJsonArray modelArray = jsonObject["data"].toArray();
QStringList models;
if (process.exitCode() == 0) {
QString output = QString::fromUtf8(process.readAllStandardOutput());
QStringList lines = output.split('\n', Qt::SkipEmptyParts);
// Skip the header lines
for (int i = 2; i < lines.size(); ++i) {
QString line = lines[i].trimmed();
if (!line.isEmpty()) {
// The model name is the first column
QString modelName = line.split(QRegularExpression("\\s+"), Qt::SkipEmptyParts)
.first();
models.append(modelName);
}
for (const QJsonValue &value : modelArray) {
QJsonObject modelObject = value.toObject();
QString modelId = modelObject["id"].toString();
models.append(modelId);
}
qDebug() << "Models:" << models;
} else {
// Handle error
qWarning() << "Error running 'lms list':" << process.errorString();
logMessage(QString("Error fetching models: %1").arg(reply->errorString()));
}
reply->deleteLater();
return models;
}

View File

@ -23,10 +23,11 @@
#include <QJsonDocument>
#include <QJsonObject>
#include <QNetworkReply>
#include <QProcess>
#include <QtCore/qeventloop.h>
#include "PromptTemplateManager.hpp"
#include "QodeAssistSettings.hpp"
#include "QodeAssistUtils.hpp"
namespace QodeAssist::Providers {
@ -96,50 +97,31 @@ bool OllamaProvider::handleResponse(QNetworkReply *reply, QString &accumulatedRe
QList<QString> OllamaProvider::getInstalledModels(const Utils::Environment &env)
{
QProcess process;
process.setEnvironment(env.toStringList());
QString ollamaConsoleName;
#ifdef Q_OS_WIN
ollamaConsoleName = "ollama.exe";
#else
ollamaConsoleName = "ollama";
#endif
QList<QString> models;
QNetworkAccessManager manager;
QNetworkRequest request(QUrl(url() + "/api/tags"));
QNetworkReply *reply = manager.get(request);
auto ollamaPath = env.searchInPath(ollamaConsoleName).toString();
QEventLoop loop;
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec();
if (!QFileInfo::exists(ollamaPath)) {
qWarning() << "Ollama executable not found at" << ollamaPath;
return {};
}
if (reply->error() == QNetworkReply::NoError) {
QByteArray responseData = reply->readAll();
QJsonDocument jsonResponse = QJsonDocument::fromJson(responseData);
QJsonObject jsonObject = jsonResponse.object();
QJsonArray modelArray = jsonObject["models"].toArray();
process.start(ollamaPath, QStringList() << "list");
if (!process.waitForStarted()) {
qWarning() << "Failed to start Ollama process:" << process.errorString();
return {};
}
if (!process.waitForFinished()) {
qWarning() << "Ollama process did not finish:" << process.errorString();
return {};
}
QStringList models;
if (process.exitCode() == 0) {
QString output = QString::fromUtf8(process.readAllStandardOutput());
QStringList lines = output.split('\n', Qt::SkipEmptyParts);
for (int i = 1; i < lines.size(); ++i) {
QString line = lines[i].trimmed();
if (!line.isEmpty()) {
QString modelName = line.split(QRegularExpression("\\s+"), Qt::SkipEmptyParts)
.first();
models.append(modelName);
}
for (const QJsonValue &value : modelArray) {
QJsonObject modelObject = value.toObject();
QString modelName = modelObject["name"].toString();
models.append(modelName);
}
} else {
qWarning() << "Error running 'ollama list':" << process.errorString();
logMessage(QString("Error fetching models: %1").arg(reply->errorString()));
}
reply->deleteLater();
return models;
}

View File

@ -23,7 +23,6 @@
#include <QJsonDocument>
#include <QJsonObject>
#include <QNetworkReply>
#include <QProcess>
#include "PromptTemplateManager.hpp"
#include "QodeAssistSettings.hpp"