From dbe674eecfd729a78ac4d78e1b3cb645d6c8f8e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sun, 27 Apr 2025 01:55:43 -0300 Subject: [PATCH] Remember last used model in AI Assistant. Minor change in goToNext and goToPrev in linter errors/warnings. And a couple of nits. --- src/tools/ecode/featureshealth.cpp | 3 +- .../plugins/aiassistant/aiassistantplugin.cpp | 39 +++++++++++++++---- .../plugins/aiassistant/aiassistantplugin.hpp | 11 +++++- .../ecode/plugins/aiassistant/chatui.cpp | 18 +++++++-- .../ecode/plugins/aiassistant/chatui.hpp | 4 ++ .../ecode/plugins/debugger/debuggerplugin.cpp | 5 ++- .../ecode/plugins/debugger/debuggerplugin.hpp | 2 +- .../ecode/plugins/linter/linterplugin.cpp | 26 ++++++++++++- .../ecode/plugins/linter/linterplugin.hpp | 2 +- 9 files changed, 90 insertions(+), 20 deletions(-) diff --git a/src/tools/ecode/featureshealth.cpp b/src/tools/ecode/featureshealth.cpp index 37ccfee64..a588c583d 100644 --- a/src/tools/ecode/featureshealth.cpp +++ b/src/tools/ecode/featureshealth.cpp @@ -452,11 +452,10 @@ void FeaturesHealth::displayHealth( PluginManager* pluginManager, UISceneNode* s - + diff --git a/src/tools/ecode/plugins/aiassistant/aiassistantplugin.cpp b/src/tools/ecode/plugins/aiassistant/aiassistantplugin.cpp index ca8c69075..badfd313d 100644 --- a/src/tools/ecode/plugins/aiassistant/aiassistantplugin.cpp +++ b/src/tools/ecode/plugins/aiassistant/aiassistantplugin.cpp @@ -132,9 +132,25 @@ AIAssistantPlugin::AIAssistantPlugin( PluginManager* pluginManager, bool sync ) load( pluginManager ); #endif } + + if ( getUISceneNode() ) { + getPluginContext()->getSplitter()->forEachWidgetClass( + "llm_chatui", [this]( UIWidget* widget ) { + LLMChatUI* chat = static_cast( widget ); + chat->setManager( getManager() ); + } ); + } } AIAssistantPlugin::~AIAssistantPlugin() { + if ( SceneManager::existsSingleton() && !SceneManager::instance()->isShuttingDown() ) { + getPluginContext()->getSplitter()->forEachWidgetClass( + "llm_chatui", []( UIWidget* widget ) { + LLMChatUI* chat = static_cast( widget ); + chat->setManager( nullptr ); + } ); + } + waitUntilLoaded(); mShuttingDown = true; if ( mStatusButton ) @@ -508,17 +524,24 @@ void AIAssistantPlugin::onSaveState( IniFile* state ) { if ( mainChat == nullptr && !chats.empty() ) mainChat = chats[chats.size() - 1]; - if ( mainChat == nullptr ) + AIAssistantConfig config; + + if ( mainChat != nullptr ) { + config.partition = mainChat->getSplitter()->getSplitPartition(); + config.modelProvider = mainChat->getCurModel().provider; + config.modelName = mainChat->getCurModel().name; + } else { + config = mConfig; + } + + if ( mConfig.modelName.empty() || mConfig.modelProvider.empty() || + mConfig.partition.getValue() == 0 ) return; - auto partition = mainChat->getSplitter()->getSplitPartition(); - auto modelProvider = mainChat->getCurModel().provider; - auto modelName = mainChat->getCurModel().name; - const std::string keyname = "aiassistant"; - state->setValue( keyname, "split_partition", partition.toString() ); - state->setValue( keyname, "default_provider", modelProvider ); - state->setValue( keyname, "default_model", modelName ); + state->setValue( keyname, "split_partition", config.partition.toString() ); + state->setValue( keyname, "default_provider", config.modelProvider ); + state->setValue( keyname, "default_model", config.modelName ); } } // namespace ecode diff --git a/src/tools/ecode/plugins/aiassistant/aiassistantplugin.hpp b/src/tools/ecode/plugins/aiassistant/aiassistantplugin.hpp index 494bbdd12..66d385c6a 100644 --- a/src/tools/ecode/plugins/aiassistant/aiassistantplugin.hpp +++ b/src/tools/ecode/plugins/aiassistant/aiassistantplugin.hpp @@ -10,9 +10,15 @@ class LLMChatUI; class AIAssistantPlugin : public PluginBase { public: + struct AIAssistantConfig { + StyleSheetLength partition; + std::string modelProvider; + std::string modelName; + }; + static PluginDefinition Definition() { return { "aiassistant", "AI Assistant", "Chat with your favorite AI assistant", - AIAssistantPlugin::New, { 0, 0, 1 }, AIAssistantPlugin::NewSync }; + AIAssistantPlugin::New, { 0, 0, 2 }, AIAssistantPlugin::NewSync }; } static Plugin* New( PluginManager* pluginManager ); @@ -40,12 +46,15 @@ class AIAssistantPlugin : public PluginBase { void onSaveState( IniFile* state ) override; + void setConfig( AIAssistantConfig config ) { mConfig = std::move( config ); } + protected: LLMProviders mProviders; bool mUIInit{ false }; UIWidget* mStatusBar{ nullptr }; UIPushButton* mStatusButton{ nullptr }; UnorderedMap mApiKeys; + AIAssistantConfig mConfig; AIAssistantPlugin( PluginManager* pluginManager, bool sync ); diff --git a/src/tools/ecode/plugins/aiassistant/chatui.cpp b/src/tools/ecode/plugins/aiassistant/chatui.cpp index 2d7114d7a..8a7390cdc 100644 --- a/src/tools/ecode/plugins/aiassistant/chatui.cpp +++ b/src/tools/ecode/plugins/aiassistant/chatui.cpp @@ -475,6 +475,16 @@ LLMChatUI::LLMChatUI( PluginManager* manager ) : addKb( mChatInput, "mod+shift+keypad enter", "ai-add-chat", true, false ); } +LLMChatUI::~LLMChatUI() { + if ( getPlugin() ) { + AIAssistantPlugin::AIAssistantConfig config; + config.partition = getSplitter()->getSplitPartition(); + config.modelProvider = getCurModel().provider; + config.modelName = getCurModel().name; + getPlugin()->setConfig( std::move( config ) ); + } +} + void LLMChatUI::addKb( UICodeEditor* editor, std::string kb, const std::string& cmd, bool bindToChatUI, bool searchDefined ) { if ( searchDefined && getPlugin() ) { @@ -1229,9 +1239,11 @@ void LLMChatUI::showMsg( String msg ) { } AIAssistantPlugin* LLMChatUI::getPlugin() const { - auto plugin = mManager->get( "aiassistant" ); - if ( plugin ) - return reinterpret_cast( plugin ); + if ( mManager != nullptr ) { + auto plugin = mManager->get( "aiassistant" ); + if ( plugin ) + return reinterpret_cast( plugin ); + } return nullptr; } diff --git a/src/tools/ecode/plugins/aiassistant/chatui.hpp b/src/tools/ecode/plugins/aiassistant/chatui.hpp index 3a109926b..396280f71 100644 --- a/src/tools/ecode/plugins/aiassistant/chatui.hpp +++ b/src/tools/ecode/plugins/aiassistant/chatui.hpp @@ -50,6 +50,8 @@ class LLMChatUI : public UILinearLayout, public WidgetCommandExecuter { public: static LLMChatUI* New( PluginManager* manager ) { return eeNew( LLMChatUI, ( manager ) ); } + virtual ~LLMChatUI(); + nlohmann::json serialize(); std::string unserialize( const nlohmann::json& payload ); // returns the input value @@ -83,6 +85,8 @@ class LLMChatUI : public UILinearLayout, public WidgetCommandExecuter { bool isLocked() const { return mChatLocked; } + void setManager( PluginManager* manager ) { mManager = manager; } + protected: UUID mUUID; std::string mSummary; diff --git a/src/tools/ecode/plugins/debugger/debuggerplugin.cpp b/src/tools/ecode/plugins/debugger/debuggerplugin.cpp index c97dd9543..d82a687c6 100644 --- a/src/tools/ecode/plugins/debugger/debuggerplugin.cpp +++ b/src/tools/ecode/plugins/debugger/debuggerplugin.cpp @@ -1,3 +1,4 @@ +#include "debuggerplugin.hpp" #include "../../notificationcenter.hpp" #include "../../terminalmanager.hpp" #include "../../uistatusbar.hpp" @@ -6,7 +7,6 @@ #include "bussocket.hpp" #include "bussocketprocess.hpp" #include "dap/debuggerclientdap.hpp" -#include "debuggerplugin.hpp" #include "models/breakpointsmodel.hpp" #include "models/processesmodel.hpp" #include "models/variablesmodel.hpp" @@ -130,7 +130,8 @@ DebuggerPlugin::~DebuggerPlugin() { mDebugger.reset(); mListener.reset(); - if ( !isShuttingDown() && getPluginContext()->getMainLayout() ) { + if ( SceneManager::existsSingleton() && !SceneManager::instance()->isShuttingDown() && + getPluginContext() && getPluginContext()->getMainLayout() ) { for ( const auto& kb : mKeyBindings ) getPluginContext()->getMainLayout()->getKeyBindings().removeCommandKeybind( kb.first ); } diff --git a/src/tools/ecode/plugins/debugger/debuggerplugin.hpp b/src/tools/ecode/plugins/debugger/debuggerplugin.hpp index e39ed1309..ad1e38b9d 100644 --- a/src/tools/ecode/plugins/debugger/debuggerplugin.hpp +++ b/src/tools/ecode/plugins/debugger/debuggerplugin.hpp @@ -51,7 +51,7 @@ class DebuggerPlugin : public PluginBase { public: static PluginDefinition Definition() { return { "debugger", "Debugger", "Debugger integration", - DebuggerPlugin::New, { 0, 0, 2 }, DebuggerPlugin::NewSync }; + DebuggerPlugin::New, { 0, 0, 3 }, DebuggerPlugin::NewSync }; } static Plugin* New( PluginManager* pluginManager ); diff --git a/src/tools/ecode/plugins/linter/linterplugin.cpp b/src/tools/ecode/plugins/linter/linterplugin.cpp index 108087c37..3a1633184 100644 --- a/src/tools/ecode/plugins/linter/linterplugin.cpp +++ b/src/tools/ecode/plugins/linter/linterplugin.cpp @@ -1187,6 +1187,9 @@ void LinterPlugin::goToNextError( UICodeEditor* editor ) { break; } } + + if ( matched ) + break; } else { matched = &match.second.front(); break; @@ -1197,6 +1200,7 @@ void LinterPlugin::goToNextError( UICodeEditor* editor ) { if ( matched != nullptr ) { editor->goToLine( matched->range.start() ); mManager->getSplitter()->addCurrentPositionToNavigationHistory(); + return; } else { if ( mGoToIgnoreWarnings ) { for ( const auto& m : matches ) { @@ -1205,7 +1209,7 @@ void LinterPlugin::goToNextError( UICodeEditor* editor ) { if ( lm.type == LinterType::Error ) { editor->goToLine( lm.range.start() ); mManager->getSplitter()->addCurrentPositionToNavigationHistory(); - break; + return; } } } else { @@ -1215,8 +1219,15 @@ void LinterPlugin::goToNextError( UICodeEditor* editor ) { } else if ( matches.begin()->second.front().range.start().line() != pos.line() ) { editor->goToLine( matches.begin()->second.front().range.start() ); mManager->getSplitter()->addCurrentPositionToNavigationHistory(); + return; } } + + if ( mGoToIgnoreWarnings ) { + mGoToIgnoreWarnings = false; + goToNextError( editor ); + mGoToIgnoreWarnings = true; + } } void LinterPlugin::goToPrevError( UICodeEditor* editor ) { @@ -1243,6 +1254,9 @@ void LinterPlugin::goToPrevError( UICodeEditor* editor ) { break; } } + + if ( matched ) + break; } else { matched = &match->second.front(); break; @@ -1253,6 +1267,7 @@ void LinterPlugin::goToPrevError( UICodeEditor* editor ) { if ( matched != nullptr ) { editor->goToLine( matched->range.start() ); mManager->getSplitter()->addCurrentPositionToNavigationHistory(); + return; } else { if ( mGoToIgnoreWarnings ) { for ( auto m = matches.rbegin(); m != matches.rend(); ++m ) { @@ -1261,7 +1276,7 @@ void LinterPlugin::goToPrevError( UICodeEditor* editor ) { if ( lm.type == LinterType::Error ) { editor->goToLine( lm.range.start() ); mManager->getSplitter()->addCurrentPositionToNavigationHistory(); - break; + return; } } } else { @@ -1271,8 +1286,15 @@ void LinterPlugin::goToPrevError( UICodeEditor* editor ) { } else if ( matches.rbegin()->second.front().range.start().line() != pos.line() ) { editor->goToLine( matches.rbegin()->second.front().range.start() ); mManager->getSplitter()->addCurrentPositionToNavigationHistory(); + return; } } + + if ( mGoToIgnoreWarnings ) { + mGoToIgnoreWarnings = false; + goToPrevError( editor ); + mGoToIgnoreWarnings = true; + } } bool LinterPlugin::onMouseClick( UICodeEditor* editor, const Vector2i& pos, const Uint32& flags ) { diff --git a/src/tools/ecode/plugins/linter/linterplugin.hpp b/src/tools/ecode/plugins/linter/linterplugin.hpp index da42fb1a6..41b84b415 100644 --- a/src/tools/ecode/plugins/linter/linterplugin.hpp +++ b/src/tools/ecode/plugins/linter/linterplugin.hpp @@ -59,7 +59,7 @@ class LinterPlugin : public Plugin { "Use static code analysis tool used to flag programming errors, bugs, " "stylistic errors, and suspicious constructs.", LinterPlugin::New, - { 0, 2, 6 }, + { 0, 2, 7 }, LinterPlugin::NewSync }; }