feat: Add agent roles (#287)

* feat: Add agent roles
* doc: Add agent roles to docs
This commit is contained in:
Petr Mironychev
2025-12-04 19:41:30 +01:00
committed by GitHub
parent 498eb4d932
commit fc33bb60d0
22 changed files with 1713 additions and 293 deletions

159
settings/AgentRole.cpp Normal file
View File

@ -0,0 +1,159 @@
/*
* Copyright (C) 2024-2025 Petr Mironychev
*
* This file is part of QodeAssist.
*
* QodeAssist is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QodeAssist is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QodeAssist. If not, see <https://www.gnu.org/licenses/>.
*/
#include "AgentRole.hpp"
#include <coreplugin/icore.h>
#include <QDir>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
namespace QodeAssist::Settings {
QString AgentRolesManager::getConfigurationDirectory()
{
QString path = QString("%1/qodeassist/agent_roles")
.arg(Core::ICore::userResourcePath().toFSPathString());
QDir().mkpath(path);
return path;
}
QList<AgentRole> AgentRolesManager::loadAllRoles()
{
QList<AgentRole> roles;
QString configDir = getConfigurationDirectory();
QDir dir(configDir);
ensureDefaultRoles();
const QStringList jsonFiles = dir.entryList({"*.json"}, QDir::Files);
for (const QString &fileName : jsonFiles) {
AgentRole role = loadRoleFromFile(dir.absoluteFilePath(fileName));
if (!role.id.isEmpty()) {
roles.append(role);
}
}
return roles;
}
AgentRole AgentRolesManager::loadRole(const QString &roleId)
{
if (roleId.isEmpty())
return {};
QString filePath = QDir(getConfigurationDirectory()).absoluteFilePath(roleId + ".json");
if (!QFile::exists(filePath))
return {};
return loadRoleFromFile(filePath);
}
AgentRole AgentRolesManager::loadRoleFromFile(const QString &filePath)
{
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly))
return {};
QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
if (doc.isNull() || !doc.isObject())
return {};
return AgentRole::fromJson(doc.object());
}
bool AgentRolesManager::saveRole(const AgentRole &role)
{
if (role.id.isEmpty())
return false;
QString filePath = QDir(getConfigurationDirectory()).absoluteFilePath(role.id + ".json");
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly))
return false;
QJsonDocument doc(role.toJson());
file.write(doc.toJson(QJsonDocument::Indented));
return true;
}
bool AgentRolesManager::deleteRole(const QString &roleId)
{
if (roleId.isEmpty())
return false;
QString filePath = QDir(getConfigurationDirectory()).absoluteFilePath(roleId + ".json");
return QFile::remove(filePath);
}
bool AgentRolesManager::roleExists(const QString &roleId)
{
if (roleId.isEmpty())
return false;
QString filePath = QDir(getConfigurationDirectory()).absoluteFilePath(roleId + ".json");
return QFile::exists(filePath);
}
void AgentRolesManager::ensureDefaultRoles()
{
QDir dir(getConfigurationDirectory());
if (!dir.exists("developer.json"))
saveRole(getDefaultDeveloperRole());
if (!dir.exists("reviewer.json"))
saveRole(getDefaultReviewerRole());
}
AgentRole AgentRolesManager::getDefaultDeveloperRole()
{
return AgentRole{
"developer",
"Developer",
"General coding assistance and implementation",
"You are an advanced AI assistant specializing in C++, Qt, and QML development. "
"Your role is to provide helpful, accurate, and detailed responses to questions "
"about coding, debugging, and best practices in these technologies. "
"Focus on writing clean, maintainable code following industry standards.",
false};
}
AgentRole AgentRolesManager::getDefaultReviewerRole()
{
return AgentRole{
"reviewer",
"Code Reviewer",
"Code review, quality assurance, and best practices",
"You are an expert code reviewer specializing in C++, Qt, and QML. "
"Your role is to:\n"
"- Identify potential bugs, memory leaks, and performance issues\n"
"- Check adherence to coding standards and best practices\n"
"- Suggest improvements for readability and maintainability\n"
"- Verify proper error handling and edge cases\n"
"- Ensure thread safety and proper Qt object lifetime management\n"
"Provide constructive, specific feedback with examples.",
false};
}
} // namespace QodeAssist::Settings

81
settings/AgentRole.hpp Normal file
View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2024-2025 Petr Mironychev
*
* This file is part of QodeAssist.
*
* QodeAssist is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QodeAssist is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QodeAssist. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <QJsonObject>
#include <QList>
#include <QString>
namespace QodeAssist::Settings {
struct AgentRole
{
QString id;
QString name;
QString description;
QString systemPrompt;
bool isBuiltin = false;
QJsonObject toJson() const
{
return QJsonObject{
{"id", id},
{"name", name},
{"description", description},
{"systemPrompt", systemPrompt},
{"isBuiltin", isBuiltin}};
}
static AgentRole fromJson(const QJsonObject &json)
{
return AgentRole{
json["id"].toString(),
json["name"].toString(),
json["description"].toString(),
json["systemPrompt"].toString(),
json["isBuiltin"].toBool(false)};
}
bool operator==(const AgentRole &other) const { return id == other.id; }
};
class AgentRolesManager
{
public:
static QString getConfigurationDirectory();
static QList<AgentRole> loadAllRoles();
static AgentRole loadRole(const QString &roleId);
static AgentRole loadRoleFromFile(const QString &filePath);
static bool saveRole(const AgentRole &role);
static bool deleteRole(const QString &roleId);
static bool roleExists(const QString &roleId);
static void ensureDefaultRoles();
static AgentRole getNoRole()
{
return AgentRole{"", "No Role", "Use base system prompt without role specialization", "", false};
}
private:
static AgentRole getDefaultDeveloperRole();
static AgentRole getDefaultReviewerRole();
};
} // namespace QodeAssist::Settings

View File

@ -0,0 +1,122 @@
/*
* Copyright (C) 2024-2025 Petr Mironychev
*
* This file is part of QodeAssist.
*
* QodeAssist is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QodeAssist is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QodeAssist. If not, see <https://www.gnu.org/licenses/>.
*/
#include "AgentRoleDialog.hpp"
#include <QDialogButtonBox>
#include <QFormLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QTextEdit>
#include <QVBoxLayout>
namespace QodeAssist::Settings {
AgentRoleDialog::AgentRoleDialog(QWidget *parent)
: QDialog(parent)
, m_editMode(false)
{
setWindowTitle(tr("Add Agent Role"));
setupUI();
}
AgentRoleDialog::AgentRoleDialog(const AgentRole &role, bool editMode, QWidget *parent)
: QDialog(parent)
, m_editMode(editMode)
{
setWindowTitle(editMode ? tr("Edit Agent Role") : tr("Duplicate Agent Role"));
setupUI();
setRole(role);
}
void AgentRoleDialog::setupUI()
{
auto *mainLayout = new QVBoxLayout(this);
auto *formLayout = new QFormLayout();
m_nameEdit = new QLineEdit(this);
m_nameEdit->setPlaceholderText(tr("e.g., Developer, Code Reviewer"));
formLayout->addRow(tr("Name:"), m_nameEdit);
m_idEdit = new QLineEdit(this);
m_idEdit->setPlaceholderText(tr("e.g., developer, code_reviewer"));
formLayout->addRow(tr("ID:"), m_idEdit);
m_descriptionEdit = new QTextEdit(this);
m_descriptionEdit->setPlaceholderText(tr("Brief description of this role..."));
m_descriptionEdit->setMaximumHeight(80);
formLayout->addRow(tr("Description:"), m_descriptionEdit);
mainLayout->addLayout(formLayout);
auto *promptLabel = new QLabel(tr("System Prompt:"), this);
mainLayout->addWidget(promptLabel);
m_systemPromptEdit = new QTextEdit(this);
m_systemPromptEdit->setPlaceholderText(
tr("You are an expert in...\n\nYour role is to:\n- Task 1\n- Task 2\n- Task 3"));
mainLayout->addWidget(m_systemPromptEdit);
m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
mainLayout->addWidget(m_buttonBox);
connect(m_buttonBox, &QDialogButtonBox::accepted, this, &AgentRoleDialog::accept);
connect(m_buttonBox, &QDialogButtonBox::rejected, this, &AgentRoleDialog::reject);
connect(m_nameEdit, &QLineEdit::textChanged, this, &AgentRoleDialog::validateInput);
connect(m_idEdit, &QLineEdit::textChanged, this, &AgentRoleDialog::validateInput);
connect(m_systemPromptEdit, &QTextEdit::textChanged, this, &AgentRoleDialog::validateInput);
if (m_editMode) {
m_idEdit->setEnabled(false);
m_idEdit->setToolTip(tr("ID cannot be changed for existing roles"));
}
setMinimumSize(600, 500);
validateInput();
}
void AgentRoleDialog::validateInput()
{
bool valid = !m_nameEdit->text().trimmed().isEmpty()
&& !m_idEdit->text().trimmed().isEmpty()
&& !m_systemPromptEdit->toPlainText().trimmed().isEmpty();
m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid);
}
AgentRole AgentRoleDialog::getRole() const
{
return AgentRole{
m_idEdit->text().trimmed(),
m_nameEdit->text().trimmed(),
m_descriptionEdit->toPlainText().trimmed(),
m_systemPromptEdit->toPlainText().trimmed(),
false};
}
void AgentRoleDialog::setRole(const AgentRole &role)
{
m_idEdit->setText(role.id);
m_nameEdit->setText(role.name);
m_descriptionEdit->setPlainText(role.description);
m_systemPromptEdit->setPlainText(role.systemPrompt);
}
} // namespace QodeAssist::Settings

View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2024-2025 Petr Mironychev
*
* This file is part of QodeAssist.
*
* QodeAssist is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QodeAssist is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QodeAssist. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <QDialog>
#include "AgentRole.hpp"
class QLineEdit;
class QTextEdit;
class QDialogButtonBox;
namespace QodeAssist::Settings {
class AgentRoleDialog : public QDialog
{
Q_OBJECT
public:
explicit AgentRoleDialog(QWidget *parent = nullptr);
explicit AgentRoleDialog(const AgentRole &role, bool editMode = true, QWidget *parent = nullptr);
AgentRole getRole() const;
void setRole(const AgentRole &role);
private:
void setupUI();
void validateInput();
QLineEdit *m_nameEdit = nullptr;
QLineEdit *m_idEdit = nullptr;
QTextEdit *m_descriptionEdit = nullptr;
QTextEdit *m_systemPromptEdit = nullptr;
QDialogButtonBox *m_buttonBox = nullptr;
bool m_editMode = false;
};
} // namespace QodeAssist::Settings

View File

@ -0,0 +1,264 @@
/*
* Copyright (C) 2024-2025 Petr Mironychev
*
* This file is part of QodeAssist.
*
* QodeAssist is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QodeAssist is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QodeAssist. If not, see <https://www.gnu.org/licenses/>.
*/
#include "AgentRolesWidget.hpp"
#include "AgentRole.hpp"
#include "AgentRoleDialog.hpp"
#include "SettingsTr.hpp"
#include <QDesktopServices>
#include <QHBoxLayout>
#include <QLabel>
#include <QListWidget>
#include <QMessageBox>
#include <QPushButton>
#include <QUrl>
#include <QVBoxLayout>
namespace QodeAssist::Settings {
AgentRolesWidget::AgentRolesWidget(QWidget *parent)
: QWidget(parent)
{
setupUI();
loadRoles();
}
void AgentRolesWidget::setupUI()
{
auto *mainLayout = new QVBoxLayout(this);
auto *headerLayout = new QHBoxLayout();
auto *infoLabel = new QLabel(
Tr::tr("Agent roles define different system prompts for specific tasks."), this);
infoLabel->setWordWrap(true);
headerLayout->addWidget(infoLabel, 1);
auto *openFolderButton = new QPushButton(Tr::tr("Open Roles Folder..."), this);
connect(openFolderButton, &QPushButton::clicked, this, &AgentRolesWidget::onOpenRolesFolder);
headerLayout->addWidget(openFolderButton);
mainLayout->addLayout(headerLayout);
auto *contentLayout = new QHBoxLayout();
m_rolesList = new QListWidget(this);
m_rolesList->setSelectionMode(QAbstractItemView::SingleSelection);
connect(m_rolesList, &QListWidget::itemSelectionChanged, this, &AgentRolesWidget::updateButtons);
connect(m_rolesList, &QListWidget::itemDoubleClicked, this, &AgentRolesWidget::onEditRole);
contentLayout->addWidget(m_rolesList, 1);
auto *buttonsLayout = new QVBoxLayout();
m_addButton = new QPushButton(Tr::tr("Add..."), this);
connect(m_addButton, &QPushButton::clicked, this, &AgentRolesWidget::onAddRole);
buttonsLayout->addWidget(m_addButton);
m_editButton = new QPushButton(Tr::tr("Edit..."), this);
connect(m_editButton, &QPushButton::clicked, this, &AgentRolesWidget::onEditRole);
buttonsLayout->addWidget(m_editButton);
m_duplicateButton = new QPushButton(Tr::tr("Duplicate..."), this);
connect(m_duplicateButton, &QPushButton::clicked, this, &AgentRolesWidget::onDuplicateRole);
buttonsLayout->addWidget(m_duplicateButton);
m_deleteButton = new QPushButton(Tr::tr("Delete"), this);
connect(m_deleteButton, &QPushButton::clicked, this, &AgentRolesWidget::onDeleteRole);
buttonsLayout->addWidget(m_deleteButton);
buttonsLayout->addStretch();
contentLayout->addLayout(buttonsLayout);
mainLayout->addLayout(contentLayout);
updateButtons();
}
void AgentRolesWidget::loadRoles()
{
m_rolesList->clear();
const QList<AgentRole> roles = AgentRolesManager::loadAllRoles();
for (const AgentRole &role : roles) {
auto *item = new QListWidgetItem(role.name, m_rolesList);
item->setData(Qt::UserRole, role.id);
QString tooltip = role.description;
if (role.isBuiltin) {
tooltip += "\n\n" + Tr::tr("(Built-in role)");
item->setForeground(Qt::darkGray);
}
item->setToolTip(tooltip);
}
}
void AgentRolesWidget::updateButtons()
{
QListWidgetItem *selectedItem = m_rolesList->currentItem();
bool hasSelection = selectedItem != nullptr;
bool isBuiltin = false;
if (hasSelection) {
QString roleId = selectedItem->data(Qt::UserRole).toString();
AgentRole role = AgentRolesManager::loadRole(roleId);
isBuiltin = role.isBuiltin;
}
m_editButton->setEnabled(hasSelection);
m_duplicateButton->setEnabled(hasSelection);
m_deleteButton->setEnabled(hasSelection && !isBuiltin);
}
void AgentRolesWidget::onAddRole()
{
AgentRoleDialog dialog(this);
if (dialog.exec() != QDialog::Accepted)
return;
AgentRole newRole = dialog.getRole();
if (AgentRolesManager::roleExists(newRole.id)) {
QMessageBox::warning(
this,
Tr::tr("Role Already Exists"),
Tr::tr("A role with ID '%1' already exists. Please use a different ID.")
.arg(newRole.id));
return;
}
if (AgentRolesManager::saveRole(newRole)) {
loadRoles();
} else {
QMessageBox::critical(
this, Tr::tr("Error"), Tr::tr("Failed to save role '%1'.").arg(newRole.name));
}
}
void AgentRolesWidget::onEditRole()
{
QListWidgetItem *selectedItem = m_rolesList->currentItem();
if (!selectedItem)
return;
QString roleId = selectedItem->data(Qt::UserRole).toString();
AgentRole role = AgentRolesManager::loadRole(roleId);
if (role.isBuiltin) {
QMessageBox::information(
this,
Tr::tr("Cannot Edit Built-in Role"),
Tr::tr(
"Built-in roles cannot be edited. You can duplicate this role and modify the copy."));
return;
}
AgentRoleDialog dialog(role, this);
if (dialog.exec() != QDialog::Accepted)
return;
AgentRole updatedRole = dialog.getRole();
if (AgentRolesManager::saveRole(updatedRole)) {
loadRoles();
} else {
QMessageBox::critical(
this, Tr::tr("Error"), Tr::tr("Failed to update role '%1'.").arg(updatedRole.name));
}
}
void AgentRolesWidget::onDuplicateRole()
{
QListWidgetItem *selectedItem = m_rolesList->currentItem();
if (!selectedItem)
return;
QString roleId = selectedItem->data(Qt::UserRole).toString();
AgentRole role = AgentRolesManager::loadRole(roleId);
role.name += " (Copy)";
role.id += "_copy";
role.isBuiltin = false;
int counter = 1;
QString baseId = role.id;
while (AgentRolesManager::roleExists(role.id)) {
role.id = baseId + QString::number(counter++);
}
AgentRoleDialog dialog(role, false, this);
if (dialog.exec() != QDialog::Accepted)
return;
AgentRole newRole = dialog.getRole();
if (AgentRolesManager::roleExists(newRole.id)) {
QMessageBox::warning(
this,
Tr::tr("Role Already Exists"),
Tr::tr("A role with ID '%1' already exists. Please use a different ID.")
.arg(newRole.id));
return;
}
if (AgentRolesManager::saveRole(newRole)) {
loadRoles();
} else {
QMessageBox::critical(this, Tr::tr("Error"), Tr::tr("Failed to duplicate role."));
}
}
void AgentRolesWidget::onDeleteRole()
{
QListWidgetItem *selectedItem = m_rolesList->currentItem();
if (!selectedItem)
return;
QString roleId = selectedItem->data(Qt::UserRole).toString();
AgentRole role = AgentRolesManager::loadRole(roleId);
if (role.isBuiltin) {
QMessageBox::information(
this, Tr::tr("Cannot Delete Built-in Role"), Tr::tr("Built-in roles cannot be deleted."));
return;
}
QMessageBox::StandardButton reply = QMessageBox::question(
this,
Tr::tr("Delete Role"),
Tr::tr("Are you sure you want to delete the role '%1'?").arg(role.name),
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
if (AgentRolesManager::deleteRole(roleId)) {
loadRoles();
} else {
QMessageBox::critical(
this, Tr::tr("Error"), Tr::tr("Failed to delete role '%1'.").arg(role.name));
}
}
}
void AgentRolesWidget::onOpenRolesFolder()
{
QDesktopServices::openUrl(QUrl::fromLocalFile(AgentRolesManager::getConfigurationDirectory()));
}
} // namespace QodeAssist::Settings

View File

@ -0,0 +1,54 @@
/*
* Copyright (C) 2024-2025 Petr Mironychev
*
* This file is part of QodeAssist.
*
* QodeAssist is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QodeAssist is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QodeAssist. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <QWidget>
class QListWidget;
class QPushButton;
namespace QodeAssist::Settings {
class AgentRolesWidget : public QWidget
{
Q_OBJECT
public:
explicit AgentRolesWidget(QWidget *parent = nullptr);
private:
void setupUI();
void loadRoles();
void updateButtons();
void onAddRole();
void onEditRole();
void onDuplicateRole();
void onDeleteRole();
void onOpenRolesFolder();
QListWidget *m_rolesList = nullptr;
QPushButton *m_addButton = nullptr;
QPushButton *m_editButton = nullptr;
QPushButton *m_duplicateButton = nullptr;
QPushButton *m_deleteButton = nullptr;
};
} // namespace QodeAssist::Settings

View File

@ -16,11 +16,15 @@ add_library(QodeAssistSettings STATIC
ProviderSettings.hpp ProviderSettings.cpp
PluginUpdater.hpp PluginUpdater.cpp
UpdateDialog.hpp UpdateDialog.cpp
AgentRole.hpp AgentRole.cpp
AgentRoleDialog.hpp AgentRoleDialog.cpp
AgentRolesWidget.hpp AgentRolesWidget.cpp
)
target_link_libraries(QodeAssistSettings
PUBLIC
Qt::Core
Qt::Widgets
Qt::Network
QtCreator::Core
QtCreator::Utils

View File

@ -29,6 +29,7 @@
#include "SettingsConstants.hpp"
#include "SettingsTr.hpp"
#include "SettingsUtils.hpp"
#include "AgentRolesWidget.hpp"
namespace QodeAssist::Settings {
@ -262,6 +263,9 @@ ChatAssistantSettings::ChatAssistantSettings()
chatRenderer.setDefaultValue("rhi");
#endif
lastUsedRoleId.setSettingsKey(Constants::CA_LAST_USED_ROLE);
lastUsedRoleId.setDefaultValue("");
resetToDefaults.m_buttonText = TrConstants::RESET_TO_DEFAULTS;
readSettings();
@ -405,4 +409,18 @@ public:
const ChatAssistantSettingsPage chatAssistantSettingsPage;
class AgentRolesSettingsPage : public Core::IOptionsPage
{
public:
AgentRolesSettingsPage()
{
setId("QodeAssist.AgentRoles");
setDisplayName(Tr::tr("Agent Roles"));
setCategory(Constants::QODE_ASSIST_GENERAL_OPTIONS_CATEGORY);
setWidgetCreator([]() { return new AgentRolesWidget(); });
}
};
const AgentRolesSettingsPage agentRolesSettingsPage;
} // namespace QodeAssist::Settings

View File

@ -21,6 +21,7 @@
#include <utils/aspects.h>
#include "AgentRole.hpp"
#include "ButtonAspect.hpp"
namespace QodeAssist::Settings {
@ -82,6 +83,8 @@ public:
Utils::SelectionAspect chatRenderer{this};
Utils::StringAspect lastUsedRoleId{this};
private:
void setupConnections();
void resetSettingsToDefaults();

View File

@ -209,6 +209,8 @@ const char CA_CODE_FONT_SIZE[] = "QodeAssist.caCodeFontSize";
const char CA_TEXT_FORMAT[] = "QodeAssist.caTextFormat";
const char CA_CHAT_RENDERER[] = "QodeAssist.caChatRenderer";
const char CA_LAST_USED_ROLE[] = "QodeAssist.caLastUsedRole";
// quick refactor preset prompt settings
const char QR_TEMPERATURE[] = "QodeAssist.qrTemperature";
const char QR_MAX_TOKENS[] = "QodeAssist.qrMaxTokens";