[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);