[office/skrooge] plugins/skrooge/skrooge_aiassistant: AI Assistant

Stéphane MANKOWSKI <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 83ea06a4c09d25c51f10f10ca0844e78740780e6 by Stéphane MANKOWSKI.
Committed on 01/08/2026 at 10:16.
Pushed by smankowski into branch 'master'.

AI Assistant

M  +44   -5    plugins/skrooge/skrooge_aiassistant/skgassistantplugindockwidget.cpp
M  +1    -0    plugins/skrooge/skrooge_aiassistant/skgassistantplugindockwidget.h

https://invent.kde.org/office/skrooge/-/commit/83ea06a4c09d25c51f10f10ca0844e78740780e6

diff --git a/plugins/skrooge/skrooge_aiassistant/skgassistantplugindockwidget.cpp b/plugins/skrooge/skrooge_aiassistant/skgassistantplugindockwidget.cpp
index 2bed20ab1..6bed278ca 100644
--- a/plugins/skrooge/skrooge_aiassistant/skgassistantplugindockwidget.cpp
+++ b/plugins/skrooge/skrooge_aiassistant/skgassistantplugindockwidget.cpp
@@ -250,6 +250,7 @@ void SKGAssistantPluginDockWidget::sendCompletionRequest()
     QJsonObject payload;
     payload.insert(QStringLiteral("messages"), getRequestMessages(m_messages));
     payload.insert(QStringLiteral("temperature"), 1.0);
+    payload.insert(QStringLiteral("max_tokens"), 100000);
     payload.insert(QStringLiteral("stream"), false);
     payload.insert(QStringLiteral("tools"), getTools());
 
@@ -321,6 +322,24 @@ QJsonArray SKGAssistantPluginDockWidget::getTools()
         tool.insert(QStringLiteral("function"), function);
         tools << tool;
     }
+
+    // Add the get current selection
+    if (skgassistant_settings::enableWebSearch()) {
+        QJsonObject tool;
+        tool.insert(QStringLiteral("type"), QStringLiteral("function"));
+        QJsonObject function;
+        function.insert(QStringLiteral("name"), QStringLiteral("get_current_selection"));
+        function.insert(QStringLiteral("description"), i18nc("Tool description", "Get the current selection (accounts, transactions, trackers, units ...)."));
+        QJsonObject parameters;
+        parameters.insert(QStringLiteral("type"), QStringLiteral("object"));
+        QJsonObject properties;
+        parameters.insert(QStringLiteral("properties"), properties);
+        QJsonArray required;
+        parameters.insert(QStringLiteral("required"), required);
+        function.insert(QStringLiteral("parameters"), parameters);
+        tool.insert(QStringLiteral("function"), function);
+        tools << tool;
+    }
     return tools;
 }
 
@@ -601,6 +620,24 @@ QString SKGAssistantPluginDockWidget::executeWebSearch(const QString &iQuery, in
     return QString::fromUtf8(QJsonDocument(output).toJson(QJsonDocument::Compact));
 }
 
+QString SKGAssistantPluginDockWidget::executeGetCurrentSelection() const
+{
+    const auto selectedObjects = SKGMainPanel::getMainPanel()->getSelectedObjects();
+    QString output;
+    for (const auto &obj : selectedObjects) {
+        output += "# " + obj.getDisplayName() + '\n';
+        output += "The table/view of this object is: " + obj.getTable() + '\n';
+        output += "The real table of this object is: " + obj.getRealTable() + '\n';
+        const auto attributes = obj.getAttributes();
+        for (SKGQStringQStringMap::const_iterator it = attributes.constBegin(); it != attributes.constEnd(); ++it) {
+            output += "    " + it.key() + "=[" + it.value() + ']' + '\n';
+        }
+        output += "\n\n";
+    }
+
+    return output;
+}
+
 QString SKGAssistantPluginDockWidget::executeToolCall(const QJsonObject &iToolCall) const
 {
     const QJsonObject function = iToolCall.value(QStringLiteral("function")).toObject();
@@ -631,6 +668,10 @@ QString SKGAssistantPluginDockWidget::executeToolCall(const QJsonObject &iToolCa
         return executeWebSearch(argumentsObj.value(QStringLiteral("query")).toString(), maxResults);
     }
 
+    if (name == QStringLiteral("get_current_selection")) {
+        return executeGetCurrentSelection();
+    }
+
     QJsonObject error;
     error.insert(QStringLiteral("error"), i18nc("Error message", "Unknown tool: %1", name));
     return QString::fromUtf8(QJsonDocument(error).toJson(QJsonDocument::Compact));
@@ -643,8 +684,7 @@ QString SKGAssistantPluginDockWidget::extractAssistantMessage(const QByteArray &
     QJsonParseError parseError{};
     QJsonDocument response = QJsonDocument::fromJson(iPayload, &parseError);
     if (parseError.error != QJsonParseError::NoError || !response.isObject()) {
-        oErrorMessage = i18nc("Error message", "Invalid JSON response from server.");
-        return QString();
+        return i18nc("Error message", "Invalid JSON response from server: %1", QString::fromUtf8(iPayload));
     }
 
     const QJsonObject root = response.object();
@@ -663,8 +703,7 @@ QString SKGAssistantPluginDockWidget::extractAssistantMessage(const QByteArray &
 
     QJsonArray choices = root.value(QStringLiteral("choices")).toArray();
     if (choices.isEmpty()) {
-        oErrorMessage = i18nc("Error message", "No answer returned by the model.");
-        return QString();
+        return i18nc("Error message", "No answer returned by the model: %1", QString::fromUtf8(iPayload));
     }
 
     const QJsonObject firstChoice = choices.at(0).toObject();
@@ -726,7 +765,7 @@ QString SKGAssistantPluginDockWidget::extractAssistantMessage(const QByteArray &
         }
     }
     if (answer.isEmpty()) {
-        oErrorMessage = i18nc("Error message", "The model returned an empty answer.");
+        answer = i18nc("Error message", "Oops, sorry, I lost my train of thought. Could you rephrase the question?");
     }
     return answer;
 }
diff --git a/plugins/skrooge/skrooge_aiassistant/skgassistantplugindockwidget.h b/plugins/skrooge/skrooge_aiassistant/skgassistantplugindockwidget.h
index ac3c7fe81..afcacce9c 100644
--- a/plugins/skrooge/skrooge_aiassistant/skgassistantplugindockwidget.h
+++ b/plugins/skrooge/skrooge_aiassistant/skgassistantplugindockwidget.h
@@ -60,6 +60,7 @@ private:
     QString executeToolCall(const QJsonObject &iToolCall) const;
     QString executeSqliteSelect(const QString &iSql) const;
     QString executeWebSearch(const QString &iQuery, int iMaxResults) const;
+    QString executeGetCurrentSelection() const;
     static QJsonArray getTools();
     static QJsonArray getRequestMessages(const QJsonArray &iMessages);
     static QString sqlResultToJson(const SKGStringListList &iResult);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.