KTextAddons

ollamamanager.cpp
1/*
2 SPDX-FileCopyrightText: 2025 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5
6 Based on code from alpaka
7*/
8#include "ollamamanager.h"
9#include "core/textautogenerateengineaccessmanager.h"
10#include "ollamareply.h"
11#include "ollamasettings.h"
12#include "ollamautils.h"
13
14#include <KLocalizedString>
15
16#include <QBuffer>
17#include <QJsonArray>
18#include <QJsonDocument>
19#include <QJsonObject>
20#include <QNetworkReply>
21#include <QNetworkRequest>
22
23using namespace Qt::Literals::StringLiterals;
24OllamaManager::OllamaManager(QObject *parent)
25 : QObject{parent}
26{
27}
28
29OllamaManager::~OllamaManager() = default;
30
31OllamaManager *OllamaManager::self()
32{
33 static OllamaManager s_self;
34 return &s_self;
35}
36
37void OllamaManager::downloadModel(const QString &modelName)
38{
39 QNetworkRequest req{QUrl::fromUserInput(OllamaSettings::serverUrl().toString() + OllamaUtils::pullPath())};
40 req.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/json"));
41 QJsonObject data;
42 data["model"_L1] = modelName;
43 auto buf = new QBuffer{this};
44 buf->setData(QJsonDocument(data).toJson(QJsonDocument::Compact));
45
46 auto reply = new OllamaReply{TextAutogenerateText::TextAutogenerateEngineAccessManager::self()->networkManager()->post(req, buf), this};
47 connect(reply, &OllamaReply::finished, this, [this, reply, buf] {
48 Q_EMIT finished(reply->readResponse());
49 buf->deleteLater();
50 });
51 // return reply;
52 // TODO
53}
54
55void OllamaManager::loadModels()
56{
57 QNetworkRequest req{QUrl::fromUserInput(OllamaSettings::serverUrl().toString() + OllamaUtils::tagsPath())};
58 req.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/json"));
59
60 auto rep = TextAutogenerateText::TextAutogenerateEngineAccessManager::self()->networkManager()->get(req);
61 mOllamaCheckConnect = connect(rep, &QNetworkReply::finished, this, [this, rep] {
62 if (rep->error() != QNetworkReply::NoError) {
63 ModelsInfo info;
64 info.errorOccured = i18n("Failed to connect to interface at %1: %2", OllamaSettings::serverUrl().toString(), rep->errorString());
65 info.hasError = true;
66 Q_EMIT modelsLoadDone(std::move(info));
67 return;
68 }
69
70 ModelsInfo info;
71 const auto json = QJsonDocument::fromJson(rep->readAll());
72 const auto models = json["models"_L1].toArray();
73 for (const QJsonValue &model : models) {
74 info.models.push_back(model["name"_L1].toString());
75 }
76 info.isReady = !info.models.isEmpty();
77 info.hasError = false;
78 Q_EMIT modelsLoadDone(std::move(info));
79 });
80}
81
82OllamaReply *OllamaManager::getCompletion(const OllamaRequest &request)
83{
84 QNetworkRequest req{QUrl::fromUserInput(OllamaSettings::serverUrl().toString() + OllamaUtils::completionPath())};
85 req.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/json"));
86 QJsonObject data;
87 // data["model"_L1] = request.model().isEmpty() ? m_models.constFirst() : request.model();
88 data["prompt"_L1] = request.message();
89 data["model"_L1] = OllamaSettings::model();
90 const auto context = request.context().toJson();
91 if (!context.isNull()) {
92 data["context"_L1] = context;
93 }
94 if (!OllamaSettings::systemPrompt().isEmpty()) {
95 data["system"_L1] = OllamaSettings::systemPrompt();
96 }
97 auto buf = new QBuffer{this};
98 buf->setData(QJsonDocument(data).toJson(QJsonDocument::Compact));
99
100 auto reply = new OllamaReply{TextAutogenerateText::TextAutogenerateEngineAccessManager::self()->networkManager()->post(req, buf), this};
101 connect(reply, &OllamaReply::finished, this, [this, reply, buf] {
102 Q_EMIT finished(reply->readResponse());
103 buf->deleteLater();
104 });
105 return reply;
106}
107
108QDebug operator<<(QDebug d, const OllamaManager::ModelsInfo &t)
109{
110 d.space() << "models:" << t.models;
111 d.space() << "hasError:" << t.hasError;
112 d.space() << "isReady:" << t.isReady;
113 return d;
114}
115#include "moc_ollamamanager.cpp"
The OllamaReply class represents a reply from an LLM.
Definition ollamareply.h:48
void finished()
Emits when the LLM has finished returning its response.
QString i18n(const char *text, const TYPE &arg...)
char * toString(const EngineQuery &query)
QDebug & space()
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
QNetworkReply * get(const QNetworkRequest &request)
QNetworkReply * post(const QNetworkRequest &request, QHttpMultiPart *multiPart)
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QUrl fromUserInput(const QString &userInput, const QString &workingDirectory, UserInputResolutionOptions options)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Apr 25 2025 12:06:13 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.