refactor: Restructure project into sources/tests layout and dissolve PluginLLMCore

This commit is contained in:
Petr Mironychev
2026-07-14 02:50:43 +02:00
parent adef7972ed
commit 34d4f2c517
348 changed files with 809 additions and 852 deletions

View File

@@ -285,7 +285,7 @@ jobs:
- name: Run unit tests - name: Run unit tests
if: startsWith(matrix.config.os, 'ubuntu') if: startsWith(matrix.config.os, 'ubuntu')
run: | run: |
xvfb-run ./build/build/test/QodeAssistTest xvfb-run ./build/build/tests/QodeAssistTest
release: release:
if: contains(github.ref, 'tags/v') if: contains(github.ref, 'tags/v')

View File

@@ -37,14 +37,8 @@ add_definitions(
) )
add_subdirectory(sources) add_subdirectory(sources)
add_subdirectory(logger)
add_subdirectory(pluginllmcore)
add_subdirectory(settings)
add_subdirectory(UIControls)
add_subdirectory(ChatView)
add_subdirectory(context)
if(GTest_FOUND) if(GTest_FOUND)
add_subdirectory(test) add_subdirectory(tests)
endif() endif()
add_qtc_plugin(QodeAssist add_qtc_plugin(QodeAssist
@@ -65,105 +59,118 @@ add_qtc_plugin(QodeAssist
QtCreator::Utils QtCreator::Utils
QtCreator::CPlusPlus QtCreator::CPlusPlus
LLMQore LLMQore
PluginLLMCore
Skills Skills
QodeAssistChatViewplugin QodeAssistChatViewplugin
SOURCES SOURCES
.github/workflows/build_cmake.yml .github/workflows/build_cmake.yml
.github/workflows/README.md .github/workflows/README.md
README.md README.md
qodeassist.cpp sources/plugin/qodeassist.cpp
QodeAssistConstants.hpp sources/plugin/QodeAssistConstants.hpp
QodeAssisttr.h sources/plugin/QodeAssisttr.h
LLMClientInterface.hpp LLMClientInterface.cpp sources/plugin/Version.hpp
RefactorContextHelper.hpp sources/plugin/ConfigurationManager.hpp sources/plugin/ConfigurationManager.cpp
templates/Templates.hpp sources/plugin/UpdateStatusWidget.hpp sources/plugin/UpdateStatusWidget.cpp
templates/CodeLlamaFim.hpp sources/llmcore/ContextData.hpp
templates/Ollama.hpp sources/llmcore/RequestType.hpp
templates/Claude.hpp sources/completion/LLMClientInterface.hpp sources/completion/LLMClientInterface.cpp
templates/OpenAI.hpp sources/completion/LSPCompletion.hpp
templates/MistralAI.hpp sources/completion/LLMSuggestion.hpp sources/completion/LLMSuggestion.cpp
templates/StarCoder2Fim.hpp sources/completion/QodeAssistClient.hpp sources/completion/QodeAssistClient.cpp
templates/Qwen25CoderFIM.hpp sources/completion/CodeHandler.hpp sources/completion/CodeHandler.cpp
templates/OpenAICompatible.hpp sources/refactor/QuickRefactorHandler.hpp sources/refactor/QuickRefactorHandler.cpp
templates/Llama3.hpp sources/refactor/RefactorContextHelper.hpp
templates/ChatML.hpp sources/refactor/RefactorSuggestion.hpp sources/refactor/RefactorSuggestion.cpp
templates/Alpaca.hpp sources/refactor/RefactorSuggestionHoverHandler.hpp sources/refactor/RefactorSuggestionHoverHandler.cpp
templates/Llama2.hpp sources/refactor/ResponseCleaner.hpp
templates/CodeLlamaQMLFim.hpp sources/templates/PromptTemplate.hpp
templates/GoogleAI.hpp sources/templates/PromptTemplateManager.hpp sources/templates/PromptTemplateManager.cpp
templates/LlamaCppFim.hpp sources/templates/IPromptProvider.hpp
templates/Qwen3CoderFIM.hpp sources/templates/PromptProviderChat.hpp
templates/OpenAIResponses.hpp sources/templates/PromptProviderFim.hpp
providers/Providers.hpp sources/templates/Templates.hpp
providers/ProviderUrlUtils.hpp sources/templates/CodeLlamaFim.hpp
providers/OllamaProvider.hpp providers/OllamaProvider.cpp sources/templates/Ollama.hpp
providers/OllamaCompatProvider.hpp providers/OllamaCompatProvider.cpp sources/templates/Claude.hpp
providers/ClaudeProvider.hpp providers/ClaudeProvider.cpp sources/templates/OpenAI.hpp
providers/OpenAIProvider.hpp providers/OpenAIProvider.cpp sources/templates/MistralAI.hpp
providers/MistralAIProvider.hpp providers/MistralAIProvider.cpp sources/templates/StarCoder2Fim.hpp
providers/LMStudioProvider.hpp providers/LMStudioProvider.cpp sources/templates/Qwen25CoderFIM.hpp
providers/LMStudioResponsesProvider.hpp providers/LMStudioResponsesProvider.cpp sources/templates/OpenAICompatible.hpp
providers/OpenAICompatProvider.hpp providers/OpenAICompatProvider.cpp sources/templates/Llama3.hpp
providers/OpenRouterAIProvider.hpp providers/OpenRouterAIProvider.cpp sources/templates/ChatML.hpp
providers/GoogleAIProvider.hpp providers/GoogleAIProvider.cpp sources/templates/Alpaca.hpp
providers/LlamaCppProvider.hpp providers/LlamaCppProvider.cpp sources/templates/Llama2.hpp
providers/CodestralProvider.hpp providers/CodestralProvider.cpp sources/templates/CodeLlamaQMLFim.hpp
providers/OpenAIResponsesProvider.hpp providers/OpenAIResponsesProvider.cpp sources/templates/GoogleAI.hpp
providers/QwenProvider.hpp providers/QwenProvider.cpp sources/templates/LlamaCppFim.hpp
providers/QwenResponsesProvider.hpp providers/QwenResponsesProvider.cpp sources/templates/Qwen3CoderFIM.hpp
providers/DeepSeekProvider.hpp providers/DeepSeekProvider.cpp sources/templates/OpenAIResponses.hpp
sources/providers/Provider.hpp sources/providers/Provider.cpp
sources/providers/ProvidersManager.hpp sources/providers/ProvidersManager.cpp
sources/providers/IProviderRegistry.hpp
sources/providers/ProviderID.hpp
sources/providers/Providers.hpp
sources/providers/ProviderUrlUtils.hpp
sources/providers/OllamaProvider.hpp sources/providers/OllamaProvider.cpp
sources/providers/OllamaCompatProvider.hpp sources/providers/OllamaCompatProvider.cpp
sources/providers/ClaudeProvider.hpp sources/providers/ClaudeProvider.cpp
sources/providers/OpenAIProvider.hpp sources/providers/OpenAIProvider.cpp
sources/providers/MistralAIProvider.hpp sources/providers/MistralAIProvider.cpp
sources/providers/LMStudioProvider.hpp sources/providers/LMStudioProvider.cpp
sources/providers/LMStudioResponsesProvider.hpp sources/providers/LMStudioResponsesProvider.cpp
sources/providers/OpenAICompatProvider.hpp sources/providers/OpenAICompatProvider.cpp
sources/providers/OpenRouterAIProvider.hpp sources/providers/OpenRouterAIProvider.cpp
sources/providers/GoogleAIProvider.hpp sources/providers/GoogleAIProvider.cpp
sources/providers/LlamaCppProvider.hpp sources/providers/LlamaCppProvider.cpp
sources/providers/CodestralProvider.hpp sources/providers/CodestralProvider.cpp
sources/providers/OpenAIResponsesProvider.hpp sources/providers/OpenAIResponsesProvider.cpp
sources/providers/QwenProvider.hpp sources/providers/QwenProvider.cpp
sources/providers/QwenResponsesProvider.hpp sources/providers/QwenResponsesProvider.cpp
sources/providers/DeepSeekProvider.hpp sources/providers/DeepSeekProvider.cpp
QodeAssist.qrc QodeAssist.qrc
LSPCompletion.hpp sources/chat/ChatOutputPane.h sources/chat/ChatOutputPane.cpp
LLMSuggestion.hpp LLMSuggestion.cpp sources/chat/NavigationPanel.hpp sources/chat/NavigationPanel.cpp
RefactorSuggestion.hpp RefactorSuggestion.cpp sources/chat/ChatDocument.hpp sources/chat/ChatDocument.cpp
RefactorSuggestionHoverHandler.hpp RefactorSuggestionHoverHandler.cpp sources/chat/ChatEditor.hpp sources/chat/ChatEditor.cpp
QodeAssistClient.hpp QodeAssistClient.cpp sources/chat/ChatEditorFactory.hpp sources/chat/ChatEditorFactory.cpp
chat/ChatOutputPane.h chat/ChatOutputPane.cpp sources/widgets/CompletionProgressHandler.hpp sources/widgets/CompletionProgressHandler.cpp
chat/NavigationPanel.hpp chat/NavigationPanel.cpp sources/widgets/CompletionErrorHandler.hpp sources/widgets/CompletionErrorHandler.cpp
chat/ChatDocument.hpp chat/ChatDocument.cpp sources/widgets/CompletionHintWidget.hpp sources/widgets/CompletionHintWidget.cpp
chat/ChatEditor.hpp chat/ChatEditor.cpp sources/widgets/CompletionHintHandler.hpp sources/widgets/CompletionHintHandler.cpp
chat/ChatEditorFactory.hpp chat/ChatEditorFactory.cpp sources/widgets/ProgressWidget.hpp sources/widgets/ProgressWidget.cpp
ConfigurationManager.hpp ConfigurationManager.cpp sources/widgets/ErrorWidget.hpp sources/widgets/ErrorWidget.cpp
CodeHandler.hpp CodeHandler.cpp sources/widgets/EditorChatButton.hpp sources/widgets/EditorChatButton.cpp
UpdateStatusWidget.hpp UpdateStatusWidget.cpp sources/widgets/EditorChatButtonHandler.hpp sources/widgets/EditorChatButtonHandler.cpp
widgets/CompletionProgressHandler.hpp widgets/CompletionProgressHandler.cpp sources/widgets/QuickRefactorDialog.hpp sources/widgets/QuickRefactorDialog.cpp
widgets/CompletionErrorHandler.hpp widgets/CompletionErrorHandler.cpp sources/widgets/CustomInstructionsManager.hpp sources/widgets/CustomInstructionsManager.cpp
widgets/CompletionHintWidget.hpp widgets/CompletionHintWidget.cpp sources/widgets/AddCustomInstructionDialog.hpp sources/widgets/AddCustomInstructionDialog.cpp
widgets/CompletionHintHandler.hpp widgets/CompletionHintHandler.cpp sources/widgets/RefactorWidget.hpp sources/widgets/RefactorWidget.cpp
widgets/ProgressWidget.hpp widgets/ProgressWidget.cpp sources/widgets/RefactorWidgetHandler.hpp sources/widgets/RefactorWidgetHandler.cpp
widgets/ErrorWidget.hpp widgets/ErrorWidget.cpp sources/widgets/ContextExtractor.hpp
widgets/EditorChatButton.hpp widgets/EditorChatButton.cpp sources/widgets/DiffStatistics.hpp
widgets/EditorChatButtonHandler.hpp widgets/EditorChatButtonHandler.cpp sources/tools/ToolsRegistration.hpp sources/tools/ToolsRegistration.cpp
widgets/QuickRefactorDialog.hpp widgets/QuickRefactorDialog.cpp sources/tools/ListProjectFilesTool.hpp sources/tools/ListProjectFilesTool.cpp
widgets/CustomInstructionsManager.hpp widgets/CustomInstructionsManager.cpp sources/tools/GetIssuesListTool.hpp sources/tools/GetIssuesListTool.cpp
widgets/AddCustomInstructionDialog.hpp widgets/AddCustomInstructionDialog.cpp sources/tools/CreateNewFileTool.hpp sources/tools/CreateNewFileTool.cpp
widgets/RefactorWidget.hpp widgets/RefactorWidget.cpp sources/tools/EditFileTool.hpp sources/tools/EditFileTool.cpp
widgets/RefactorWidgetHandler.hpp widgets/RefactorWidgetHandler.cpp sources/tools/BuildProjectTool.hpp sources/tools/BuildProjectTool.cpp
widgets/ContextExtractor.hpp sources/tools/ExecuteTerminalCommandTool.hpp sources/tools/ExecuteTerminalCommandTool.cpp
widgets/DiffStatistics.hpp sources/tools/ProjectSearchTool.hpp sources/tools/ProjectSearchTool.cpp
sources/tools/FindFileTool.hpp sources/tools/FindFileTool.cpp
QuickRefactorHandler.hpp QuickRefactorHandler.cpp sources/tools/ReadFileTool.hpp sources/tools/ReadFileTool.cpp
tools/ToolsRegistration.hpp tools/ToolsRegistration.cpp sources/tools/FileSearchUtils.hpp sources/tools/FileSearchUtils.cpp
tools/ListProjectFilesTool.hpp tools/ListProjectFilesTool.cpp sources/tools/TodoTool.hpp sources/tools/TodoTool.cpp
tools/GetIssuesListTool.hpp tools/GetIssuesListTool.cpp sources/tools/ReadOriginalHistoryTool.hpp sources/tools/ReadOriginalHistoryTool.cpp
tools/CreateNewFileTool.hpp tools/CreateNewFileTool.cpp sources/tools/SkillTool.hpp sources/tools/SkillTool.cpp
tools/EditFileTool.hpp tools/EditFileTool.cpp sources/mcp/McpServerManager.hpp sources/mcp/McpServerManager.cpp
tools/BuildProjectTool.hpp tools/BuildProjectTool.cpp sources/mcp/McpServerConnection.hpp sources/mcp/McpServerConnection.cpp
tools/ExecuteTerminalCommandTool.hpp tools/ExecuteTerminalCommandTool.cpp sources/mcp/McpClientsManager.hpp sources/mcp/McpClientsManager.cpp
tools/ProjectSearchTool.hpp tools/ProjectSearchTool.cpp sources/settings/McpClientsListAspect.hpp sources/settings/McpClientsListAspect.cpp
tools/FindFileTool.hpp tools/FindFileTool.cpp
tools/ReadFileTool.hpp tools/ReadFileTool.cpp
tools/FileSearchUtils.hpp tools/FileSearchUtils.cpp
tools/TodoTool.hpp tools/TodoTool.cpp
tools/ReadOriginalHistoryTool.hpp tools/ReadOriginalHistoryTool.cpp
tools/SkillTool.hpp tools/SkillTool.cpp
mcp/McpServerManager.hpp mcp/McpServerManager.cpp
mcp/McpServerConnection.hpp mcp/McpServerConnection.cpp
mcp/McpClientsManager.hpp mcp/McpClientsManager.cpp
settings/McpClientsListAspect.hpp settings/McpClientsListAspect.cpp
) )
target_include_directories(QodeAssist PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/sources)
get_target_property(QtCreatorCorePath QtCreator::Core LOCATION) get_target_property(QtCreatorCorePath QtCreator::Core LOCATION)
find_program(QtCreatorExecutable find_program(QtCreatorExecutable
NAMES NAMES

View File

@@ -1,29 +0,0 @@
add_library(PluginLLMCore STATIC
RequestType.hpp
Provider.hpp Provider.cpp
ProvidersManager.hpp ProvidersManager.cpp
ContextData.hpp
IPromptProvider.hpp
IProviderRegistry.hpp
PromptProviderChat.hpp
PromptProviderFim.hpp
PromptTemplate.hpp
PromptTemplateManager.hpp PromptTemplateManager.cpp
ProviderID.hpp
RulesLoader.hpp RulesLoader.cpp
ResponseCleaner.hpp
)
target_link_libraries(PluginLLMCore
PUBLIC
Qt::Core
Qt::Network
QtCreator::Core
QtCreator::Utils
QtCreator::ExtensionSystem
LLMQore
PRIVATE
QodeAssistLogger
)
target_include_directories(PluginLLMCore PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

View File

@@ -1,2 +1,7 @@
add_subdirectory(external) add_subdirectory(external)
add_subdirectory(skills) add_subdirectory(skills)
add_subdirectory(logger)
add_subdirectory(settings)
add_subdirectory(context)
add_subdirectory(UIControls)
add_subdirectory(ChatView)

View File

@@ -92,7 +92,6 @@ target_link_libraries(QodeAssistChatView
Qt::Network Qt::Network
QtCreator::Core QtCreator::Core
QtCreator::Utils QtCreator::Utils
PluginLLMCore
QodeAssistSettings QodeAssistSettings
Context Context
QodeAssistUIControlsplugin QodeAssistUIControlsplugin
@@ -102,5 +101,5 @@ target_link_libraries(QodeAssistChatView
) )
target_include_directories(QodeAssistChatView target_include_directories(QodeAssistChatView
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/sources
) )

View File

@@ -7,8 +7,8 @@
#include <LLMQore/BaseClient.hpp> #include <LLMQore/BaseClient.hpp>
#include "ChatModel.hpp" #include "ChatModel.hpp"
#include "GeneralSettings.hpp" #include "GeneralSettings.hpp"
#include "PromptTemplateManager.hpp" #include "templates/PromptTemplateManager.hpp"
#include "ProvidersManager.hpp" #include "providers/ProvidersManager.hpp"
#include "logger/Logger.hpp" #include "logger/Logger.hpp"
#include <QDateTime> #include <QDateTime>
@@ -43,7 +43,7 @@ void ChatCompressor::startCompression(const QString &chatFilePath, ChatModel *ch
} }
auto providerName = Settings::generalSettings().caProvider(); auto providerName = Settings::generalSettings().caProvider();
m_provider = PluginLLMCore::ProvidersManager::instance().getProviderByName(providerName); m_provider = Providers::ProvidersManager::instance().getProviderByName(providerName);
if (!m_provider) { if (!m_provider) {
emit compressionFailed(tr("No provider available")); emit compressionFailed(tr("No provider available"));
@@ -51,7 +51,7 @@ void ChatCompressor::startCompression(const QString &chatFilePath, ChatModel *ch
} }
auto templateName = Settings::generalSettings().caTemplate(); auto templateName = Settings::generalSettings().caTemplate();
auto promptTemplate = PluginLLMCore::PromptTemplateManager::instance().getChatTemplateByName( auto promptTemplate = Templates::PromptTemplateManager::instance().getChatTemplateByName(
templateName); templateName);
if (!promptTemplate) { if (!promptTemplate) {
@@ -169,28 +169,28 @@ QString ChatCompressor::buildCompressionPrompt() const
} }
void ChatCompressor::buildRequestPayload( void ChatCompressor::buildRequestPayload(
QJsonObject &payload, PluginLLMCore::PromptTemplate *promptTemplate) QJsonObject &payload, Templates::PromptTemplate *promptTemplate)
{ {
PluginLLMCore::ContextData context; LLMCore::ContextData context;
context.systemPrompt = QStringLiteral( context.systemPrompt = QStringLiteral(
"You are a helpful assistant that creates concise summaries of conversations. " "You are a helpful assistant that creates concise summaries of conversations. "
"Your summaries preserve key information, technical details, and the flow of discussion."); "Your summaries preserve key information, technical details, and the flow of discussion.");
QVector<PluginLLMCore::Message> messages; QVector<LLMCore::Message> messages;
for (const auto &msg : m_chatModel->getChatHistory()) { for (const auto &msg : m_chatModel->getChatHistory()) {
if (msg.role == ChatModel::ChatRole::Tool if (msg.role == ChatModel::ChatRole::Tool
|| msg.role == ChatModel::ChatRole::FileEdit || msg.role == ChatModel::ChatRole::FileEdit
|| msg.role == ChatModel::ChatRole::Thinking) || msg.role == ChatModel::ChatRole::Thinking)
continue; continue;
PluginLLMCore::Message apiMessage; LLMCore::Message apiMessage;
apiMessage.role = (msg.role == ChatModel::ChatRole::User) ? "user" : "assistant"; apiMessage.role = (msg.role == ChatModel::ChatRole::User) ? "user" : "assistant";
apiMessage.content = msg.content; apiMessage.content = msg.content;
messages.append(apiMessage); messages.append(apiMessage);
} }
PluginLLMCore::Message compressionRequest; LLMCore::Message compressionRequest;
compressionRequest.role = "user"; compressionRequest.role = "user";
compressionRequest.content = buildCompressionPrompt(); compressionRequest.content = buildCompressionPrompt();
messages.append(compressionRequest); messages.append(compressionRequest);
@@ -198,7 +198,7 @@ void ChatCompressor::buildRequestPayload(
context.history = messages; context.history = messages;
m_provider->prepareRequest( m_provider->prepareRequest(
payload, promptTemplate, context, PluginLLMCore::RequestType::Chat, false, false); payload, promptTemplate, context, LLMCore::RequestType::Chat, false, false);
} }
bool ChatCompressor::createCompressedChatFile( bool ChatCompressor::createCompressedChatFile(

View File

@@ -9,10 +9,13 @@
#include <QObject> #include <QObject>
#include <QString> #include <QString>
namespace QodeAssist::PluginLLMCore { namespace QodeAssist::Providers {
class Provider; class Provider;
} // namespace QodeAssist::Providers
namespace QodeAssist::Templates {
class PromptTemplate; class PromptTemplate;
} // namespace QodeAssist::PluginLLMCore } // namespace QodeAssist::Templates
namespace QodeAssist::Chat { namespace QodeAssist::Chat {
@@ -49,13 +52,13 @@ private:
void disconnectAllSignals(); void disconnectAllSignals();
void cleanupState(); void cleanupState();
void handleCompressionError(const QString &error); void handleCompressionError(const QString &error);
void buildRequestPayload(QJsonObject &payload, PluginLLMCore::PromptTemplate *promptTemplate); void buildRequestPayload(QJsonObject &payload, Templates::PromptTemplate *promptTemplate);
bool m_isCompressing = false; bool m_isCompressing = false;
QString m_currentRequestId; QString m_currentRequestId;
QString m_originalChatPath; QString m_originalChatPath;
QString m_accumulatedSummary; QString m_accumulatedSummary;
PluginLLMCore::Provider *m_provider = nullptr; Providers::Provider *m_provider = nullptr;
ChatModel *m_chatModel = nullptr; ChatModel *m_chatModel = nullptr;
QList<QMetaObject::Connection> m_connections; QList<QMetaObject::Connection> m_connections;

View File

@@ -4,7 +4,7 @@
#pragma once #pragma once
#include "ContextData.hpp" #include "llmcore/ContextData.hpp"
#include "MessagePart.hpp" #include "MessagePart.hpp"
#include <QAbstractListModel> #include <QAbstractListModel>

View File

@@ -26,7 +26,7 @@
#include <utils/theme/theme.h> #include <utils/theme/theme.h>
#include <utils/utilsicons.h> #include <utils/utilsicons.h>
#include "QodeAssistConstants.hpp" #include "plugin/QodeAssistConstants.hpp"
#include "AgentRoleController.hpp" #include "AgentRoleController.hpp"
#include "ChatAssistantSettings.hpp" #include "ChatAssistantSettings.hpp"
@@ -38,13 +38,13 @@
#include "InputTokenCounter.hpp" #include "InputTokenCounter.hpp"
#include "SettingsConstants.hpp" #include "SettingsConstants.hpp"
#include "Logger.hpp" #include "Logger.hpp"
#include "ProvidersManager.hpp" #include "providers/ProvidersManager.hpp"
#include "SessionFileRegistry.hpp" #include "SessionFileRegistry.hpp"
#include "context/ContextManager.hpp" #include "context/ContextManager.hpp"
#include "pluginllmcore/RulesLoader.hpp" #include "context/RulesLoader.hpp"
#include "ProjectSettings.hpp" #include "ProjectSettings.hpp"
#include "SkillsSettings.hpp" #include "SkillsSettings.hpp"
#include "sources/skills/SkillsManager.hpp" #include "skills/SkillsManager.hpp"
namespace QodeAssist::Chat { namespace QodeAssist::Chat {
@@ -74,7 +74,7 @@ QKeySequence sendMessageKeySequence()
ChatRootView::ChatRootView(QQuickItem *parent) ChatRootView::ChatRootView(QQuickItem *parent)
: QQuickItem(parent) : QQuickItem(parent)
, m_chatModel(new ChatModel(this)) , m_chatModel(new ChatModel(this))
, m_promptProvider(PluginLLMCore::PromptTemplateManager::instance()) , m_promptProvider(Templates::PromptTemplateManager::instance())
, m_clientInterface(new ClientInterface(m_chatModel, &m_promptProvider, this)) , m_clientInterface(new ClientInterface(m_chatModel, &m_promptProvider, this))
, m_fileManager(new ChatFileManager(this)) , m_fileManager(new ChatFileManager(this))
, m_isRequestInProgress(false) , m_isRequestInProgress(false)
@@ -380,7 +380,7 @@ QVariantList ChatRootView::searchSkills(const QString &query) const
if (!manager || !Settings::skillsSettings().enableSkills()) if (!manager || !Settings::skillsSettings().enableSkills())
return results; return results;
auto *project = PluginLLMCore::RulesLoader::getActiveProject(); auto *project = Context::RulesLoader::getActiveProject();
QStringList projectSkillDirs; QStringList projectSkillDirs;
if (project) { if (project) {
Settings::ProjectSettings projectSettings(project); Settings::ProjectSettings projectSettings(project);
@@ -1135,7 +1135,7 @@ QString ChatRootView::getRuleContent(int index)
if (index < 0 || index >= m_activeRules.size()) if (index < 0 || index >= m_activeRules.size())
return QString(); return QString();
return PluginLLMCore::RulesLoader::loadRuleFileContent( return Context::RulesLoader::loadRuleFileContent(
m_activeRules[index].toMap()["filePath"].toString()); m_activeRules[index].toMap()["filePath"].toString());
} }
@@ -1143,7 +1143,7 @@ void ChatRootView::refreshRules()
{ {
m_activeRules.clear(); m_activeRules.clear();
auto project = PluginLLMCore::RulesLoader::getActiveProject(); auto project = Context::RulesLoader::getActiveProject();
if (!project) { if (!project) {
emit activeRulesChanged(); emit activeRulesChanged();
emit activeRulesCountChanged(); emit activeRulesCountChanged();
@@ -1151,7 +1151,7 @@ void ChatRootView::refreshRules()
} }
auto ruleFiles auto ruleFiles
= PluginLLMCore::RulesLoader::getRuleFilesForProject(project, PluginLLMCore::RulesContext::Chat); = Context::RulesLoader::getRuleFilesForProject(project, Context::RulesContext::Chat);
for (const auto &ruleFile : ruleFiles) { for (const auto &ruleFile : ruleFiles) {
QVariantMap ruleMap; QVariantMap ruleMap;
@@ -1250,9 +1250,9 @@ QString ChatRootView::lastInfoMessage() const
bool ChatRootView::isThinkingSupport() const bool ChatRootView::isThinkingSupport() const
{ {
auto providerName = Settings::generalSettings().caProvider(); auto providerName = Settings::generalSettings().caProvider();
auto provider = PluginLLMCore::ProvidersManager::instance().getProviderByName(providerName); auto provider = Providers::ProvidersManager::instance().getProviderByName(providerName);
return provider && provider->capabilities().testFlag(PluginLLMCore::ProviderCapability::Thinking); return provider && provider->capabilities().testFlag(Providers::ProviderCapability::Thinking);
} }
bool ChatRootView::hasImageAttachments(const QStringList &attachments) const bool ChatRootView::hasImageAttachments(const QStringList &attachments) const

View File

@@ -11,7 +11,7 @@
#include "ChatFileManager.hpp" #include "ChatFileManager.hpp"
#include "ChatModel.hpp" #include "ChatModel.hpp"
#include "ClientInterface.hpp" #include "ClientInterface.hpp"
#include "pluginllmcore/PromptProviderChat.hpp" #include "templates/PromptProviderChat.hpp"
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
namespace QodeAssist::Skills { namespace QodeAssist::Skills {
@@ -271,7 +271,7 @@ private:
Skills::SkillsManager *skillsManager() const; Skills::SkillsManager *skillsManager() const;
ChatModel *m_chatModel; ChatModel *m_chatModel;
PluginLLMCore::PromptProviderChat m_promptProvider; Templates::PromptProviderChat m_promptProvider;
ClientInterface *m_clientInterface; ClientInterface *m_clientInterface;
ChatFileManager *m_fileManager; ChatFileManager *m_fileManager;
QString m_currentTemplate; QString m_currentTemplate;

View File

@@ -16,9 +16,9 @@
#include <logger/Logger.hpp> #include <logger/Logger.hpp>
#include "ChatRootView.hpp" #include "ChatRootView.hpp"
#include "QodeAssistConstants.hpp" #include "plugin/QodeAssistConstants.hpp"
#include "SessionFileRegistry.hpp" #include "SessionFileRegistry.hpp"
#include "sources/skills/SkillsManager.hpp" #include "skills/SkillsManager.hpp"
namespace { namespace {
constexpr Qt::WindowFlags baseFlags = Qt::Window | Qt::WindowTitleHint | Qt::WindowSystemMenuHint constexpr Qt::WindowFlags baseFlags = Qt::Window | Qt::WindowTitleHint | Qt::WindowSystemMenuHint

View File

@@ -13,9 +13,9 @@
#include <coreplugin/icontext.h> #include <coreplugin/icontext.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include "QodeAssistConstants.hpp" #include "plugin/QodeAssistConstants.hpp"
#include "SessionFileRegistry.hpp" #include "SessionFileRegistry.hpp"
#include "sources/skills/SkillsManager.hpp" #include "skills/SkillsManager.hpp"
namespace QodeAssist::Chat { namespace QodeAssist::Chat {

View File

@@ -38,17 +38,17 @@
#include "GeneralSettings.hpp" #include "GeneralSettings.hpp"
#include "Logger.hpp" #include "Logger.hpp"
#include "ProjectSettings.hpp" #include "ProjectSettings.hpp"
#include "ProvidersManager.hpp" #include "providers/ProvidersManager.hpp"
#include "SkillsSettings.hpp" #include "SkillsSettings.hpp"
#include "ToolsSettings.hpp" #include "ToolsSettings.hpp"
#include <RulesLoader.hpp> #include "context/RulesLoader.hpp"
#include <context/ChangesManager.h> #include <context/ChangesManager.h>
#include <sources/skills/SkillsManager.hpp> #include "skills/SkillsManager.hpp"
namespace QodeAssist::Chat { namespace QodeAssist::Chat {
ClientInterface::ClientInterface( ClientInterface::ClientInterface(
ChatModel *chatModel, PluginLLMCore::IPromptProvider *promptProvider, QObject *parent) ChatModel *chatModel, Templates::IPromptProvider *promptProvider, QObject *parent)
: QObject(parent) : QObject(parent)
, m_promptProvider(promptProvider) , m_promptProvider(promptProvider)
, m_chatModel(chatModel) , m_chatModel(chatModel)
@@ -143,7 +143,7 @@ void ClientInterface::sendMessage(
auto &chatAssistantSettings = Settings::chatAssistantSettings(); auto &chatAssistantSettings = Settings::chatAssistantSettings();
auto providerName = Settings::generalSettings().caProvider(); auto providerName = Settings::generalSettings().caProvider();
auto provider = PluginLLMCore::ProvidersManager::instance().getProviderByName(providerName); auto provider = Providers::ProvidersManager::instance().getProviderByName(providerName);
if (!provider) { if (!provider) {
LOG_MESSAGE(QString("No provider found with name: %1").arg(providerName)); LOG_MESSAGE(QString("No provider found with name: %1").arg(providerName));
@@ -158,7 +158,7 @@ void ClientInterface::sendMessage(
return; return;
} }
PluginLLMCore::ContextData context; LLMCore::ContextData context;
const bool isToolsEnabled = useTools; const bool isToolsEnabled = useTools;
@@ -172,7 +172,7 @@ void ClientInterface::sendMessage(
systemPrompt = systemPrompt + "\n\n" + role.systemPrompt; systemPrompt = systemPrompt + "\n\n" + role.systemPrompt;
} }
auto project = PluginLLMCore::RulesLoader::getActiveProject(); auto project = Context::RulesLoader::getActiveProject();
if (project) { if (project) {
systemPrompt += QString("\n# Active project: %1").arg(project->displayName()); systemPrompt += QString("\n# Active project: %1").arg(project->displayName());
@@ -194,7 +194,7 @@ void ClientInterface::sendMessage(
} }
QString projectRules QString projectRules
= PluginLLMCore::RulesLoader::loadRulesForProject(project, PluginLLMCore::RulesContext::Chat); = Context::RulesLoader::loadRulesForProject(project, Context::RulesContext::Chat);
if (!projectRules.isEmpty()) { if (!projectRules.isEmpty()) {
systemPrompt += QString("\n# Project Rules\n\n") + projectRules; systemPrompt += QString("\n# Project Rules\n\n") + projectRules;
@@ -249,7 +249,7 @@ void ClientInterface::sendMessage(
const bool toolHistory = promptTemplate->supportsToolHistory(); const bool toolHistory = promptTemplate->supportsToolHistory();
QVector<PluginLLMCore::Message> messages; QVector<LLMCore::Message> messages;
int toolCallMsgIdx = -1; int toolCallMsgIdx = -1;
for (const auto &msg : m_chatModel->getChatHistory()) { for (const auto &msg : m_chatModel->getChatHistory()) {
if (msg.role == ChatModel::ChatRole::Tool) { if (msg.role == ChatModel::ChatRole::Tool) {
@@ -258,19 +258,19 @@ void ClientInterface::sendMessage(
} }
if (toolCallMsgIdx < 0) { if (toolCallMsgIdx < 0) {
PluginLLMCore::Message assistantCall; LLMCore::Message assistantCall;
assistantCall.role = "assistant"; assistantCall.role = "assistant";
messages.append(assistantCall); messages.append(assistantCall);
toolCallMsgIdx = messages.size() - 1; toolCallMsgIdx = messages.size() - 1;
} }
PluginLLMCore::ToolCall call; LLMCore::ToolCall call;
call.id = msg.id; call.id = msg.id;
call.name = msg.toolName; call.name = msg.toolName;
call.arguments = msg.toolArguments; call.arguments = msg.toolArguments;
messages[toolCallMsgIdx].toolCalls.append(call); messages[toolCallMsgIdx].toolCalls.append(call);
PluginLLMCore::Message toolResult; LLMCore::Message toolResult;
toolResult.role = "tool"; toolResult.role = "tool";
toolResult.toolCallId = msg.id; toolResult.toolCallId = msg.id;
toolResult.toolName = msg.toolName; toolResult.toolName = msg.toolName;
@@ -285,7 +285,7 @@ void ClientInterface::sendMessage(
continue; continue;
} }
PluginLLMCore::Message apiMessage; LLMCore::Message apiMessage;
apiMessage.role = msg.role == ChatModel::ChatRole::User ? "user" : "assistant"; apiMessage.role = msg.role == ChatModel::ChatRole::User ? "user" : "assistant";
apiMessage.content = msg.content; apiMessage.content = msg.content;
@@ -305,7 +305,7 @@ void ClientInterface::sendMessage(
apiMessage.isRedacted = msg.isRedacted; apiMessage.isRedacted = msg.isRedacted;
apiMessage.signature = msg.signature; apiMessage.signature = msg.signature;
if (provider->capabilities().testFlag(PluginLLMCore::ProviderCapability::Image) if (provider->capabilities().testFlag(Providers::ProviderCapability::Image)
&& !m_chatFilePath.isEmpty() && !msg.images.isEmpty()) { && !m_chatFilePath.isEmpty() && !msg.images.isEmpty()) {
auto apiImages = loadImagesFromStorage(msg.images); auto apiImages = loadImagesFromStorage(msg.images);
if (!apiImages.isEmpty()) { if (!apiImages.isEmpty()) {
@@ -317,7 +317,7 @@ void ClientInterface::sendMessage(
} }
if (!imageFiles.isEmpty() if (!imageFiles.isEmpty()
&& !provider->capabilities().testFlag(PluginLLMCore::ProviderCapability::Image)) { && !provider->capabilities().testFlag(Providers::ProviderCapability::Image)) {
LOG_MESSAGE(QString("Provider %1 doesn't support images, %2 ignored") LOG_MESSAGE(QString("Provider %1 doesn't support images, %2 ignored")
.arg(provider->name(), QString::number(imageFiles.size()))); .arg(provider->name(), QString::number(imageFiles.size())));
} }
@@ -331,7 +331,7 @@ void ClientInterface::sendMessage(
payload, payload,
promptTemplate, promptTemplate,
context, context,
PluginLLMCore::RequestType::Chat, LLMCore::RequestType::Chat,
useTools, useTools,
useThinking); useThinking);
@@ -395,7 +395,7 @@ void ClientInterface::sendMessage(
emit requestStarted(requestId); emit requestStarted(requestId);
if (provider->capabilities().testFlag(PluginLLMCore::ProviderCapability::Tools) if (provider->capabilities().testFlag(Providers::ProviderCapability::Tools)
&& provider->toolsManager()) { && provider->toolsManager()) {
if (auto *todoTool = qobject_cast<QodeAssist::Tools::TodoTool *>( if (auto *todoTool = qobject_cast<QodeAssist::Tools::TodoTool *>(
provider->toolsManager()->tool("todo_tool"))) { provider->toolsManager()->tool("todo_tool"))) {
@@ -411,10 +411,10 @@ void ClientInterface::sendMessage(
void ClientInterface::clearMessages() void ClientInterface::clearMessages()
{ {
const auto providerName = Settings::generalSettings().caProvider(); const auto providerName = Settings::generalSettings().caProvider();
auto *provider = PluginLLMCore::ProvidersManager::instance().getProviderByName(providerName); auto *provider = Providers::ProvidersManager::instance().getProviderByName(providerName);
if (provider && !m_chatFilePath.isEmpty() if (provider && !m_chatFilePath.isEmpty()
&& provider->capabilities().testFlag(PluginLLMCore::ProviderCapability::Tools) && provider->capabilities().testFlag(Providers::ProviderCapability::Tools)
&& provider->toolsManager()) { && provider->toolsManager()) {
if (auto *todoTool = qobject_cast<QodeAssist::Tools::TodoTool *>( if (auto *todoTool = qobject_cast<QodeAssist::Tools::TodoTool *>(
provider->toolsManager()->tool("todo_tool"))) { provider->toolsManager()->tool("todo_tool"))) {
@@ -427,7 +427,7 @@ void ClientInterface::clearMessages()
void ClientInterface::cancelRequest() void ClientInterface::cancelRequest()
{ {
QSet<PluginLLMCore::Provider *> providers; QSet<Providers::Provider *> providers;
for (auto it = m_activeRequests.begin(); it != m_activeRequests.end(); ++it) { for (auto it = m_activeRequests.begin(); it != m_activeRequests.end(); ++it) {
if (it.value().provider) { if (it.value().provider) {
providers.insert(it.value().provider); providers.insert(it.value().provider);
@@ -693,10 +693,10 @@ QString ClientInterface::encodeImageToBase64(const QString &filePath) const
return imageData.toBase64(); return imageData.toBase64();
} }
QVector<PluginLLMCore::ImageAttachment> ClientInterface::loadImagesFromStorage( QVector<LLMCore::ImageAttachment> ClientInterface::loadImagesFromStorage(
const QList<ChatModel::ImageAttachment> &storedImages) const const QList<ChatModel::ImageAttachment> &storedImages) const
{ {
QVector<PluginLLMCore::ImageAttachment> apiImages; QVector<LLMCore::ImageAttachment> apiImages;
for (const auto &storedImage : storedImages) { for (const auto &storedImage : storedImages) {
QString base64Data QString base64Data
@@ -706,7 +706,7 @@ QVector<PluginLLMCore::ImageAttachment> ClientInterface::loadImagesFromStorage(
continue; continue;
} }
PluginLLMCore::ImageAttachment apiImage; LLMCore::ImageAttachment apiImage;
apiImage.data = base64Data; apiImage.data = base64Data;
apiImage.mediaType = storedImage.mediaType; apiImage.mediaType = storedImage.mediaType;
apiImage.isUrl = false; apiImage.isUrl = false;
@@ -721,10 +721,10 @@ void ClientInterface::setChatFilePath(const QString &filePath)
{ {
if (!m_chatFilePath.isEmpty() && m_chatFilePath != filePath) { if (!m_chatFilePath.isEmpty() && m_chatFilePath != filePath) {
const auto providerName = Settings::generalSettings().caProvider(); const auto providerName = Settings::generalSettings().caProvider();
auto *provider = PluginLLMCore::ProvidersManager::instance().getProviderByName(providerName); auto *provider = Providers::ProvidersManager::instance().getProviderByName(providerName);
if (provider if (provider
&& provider->capabilities().testFlag(PluginLLMCore::ProviderCapability::Tools) && provider->capabilities().testFlag(Providers::ProviderCapability::Tools)
&& provider->toolsManager()) { && provider->toolsManager()) {
if (auto *todoTool = qobject_cast<QodeAssist::Tools::TodoTool *>( if (auto *todoTool = qobject_cast<QodeAssist::Tools::TodoTool *>(
provider->toolsManager()->tool("todo_tool"))) { provider->toolsManager()->tool("todo_tool"))) {

View File

@@ -10,8 +10,8 @@
#include <QVector> #include <QVector>
#include "ChatModel.hpp" #include "ChatModel.hpp"
#include "Provider.hpp" #include "providers/Provider.hpp"
#include "pluginllmcore/IPromptProvider.hpp" #include "templates/IPromptProvider.hpp"
#include <LLMQore/BaseClient.hpp> #include <LLMQore/BaseClient.hpp>
#include <context/ContextManager.hpp> #include <context/ContextManager.hpp>
@@ -27,7 +27,7 @@ class ClientInterface : public QObject
public: public:
explicit ClientInterface( explicit ClientInterface(
ChatModel *chatModel, PluginLLMCore::IPromptProvider *promptProvider, QObject *parent = nullptr); ChatModel *chatModel, Templates::IPromptProvider *promptProvider, QObject *parent = nullptr);
~ClientInterface(); ~ClientInterface();
void setSkillsManager(Skills::SkillsManager *skillsManager); void setSkillsManager(Skills::SkillsManager *skillsManager);
@@ -79,16 +79,16 @@ private:
bool isImageFile(const QString &filePath) const; bool isImageFile(const QString &filePath) const;
QString getMediaTypeForImage(const QString &filePath) const; QString getMediaTypeForImage(const QString &filePath) const;
QString encodeImageToBase64(const QString &filePath) const; QString encodeImageToBase64(const QString &filePath) const;
QVector<PluginLLMCore::ImageAttachment> loadImagesFromStorage(const QList<ChatModel::ImageAttachment> &storedImages) const; QVector<LLMCore::ImageAttachment> loadImagesFromStorage(const QList<ChatModel::ImageAttachment> &storedImages) const;
struct RequestContext struct RequestContext
{ {
QJsonObject originalRequest; QJsonObject originalRequest;
PluginLLMCore::Provider *provider; Providers::Provider *provider;
bool dropPreToolText = false; bool dropPreToolText = false;
}; };
PluginLLMCore::IPromptProvider *m_promptProvider = nullptr; Templates::IPromptProvider *m_promptProvider = nullptr;
ChatModel *m_chatModel; ChatModel *m_chatModel;
Context::ContextManager *m_contextManager; Context::ContextManager *m_contextManager;
Skills::SkillsManager *m_skillsManager = nullptr; Skills::SkillsManager *m_skillsManager = nullptr;

View File

@@ -16,7 +16,7 @@
#include "ChatModel.hpp" #include "ChatModel.hpp"
#include "GeneralSettings.hpp" #include "GeneralSettings.hpp"
#include "Logger.hpp" #include "Logger.hpp"
#include "ProvidersManager.hpp" #include "providers/ProvidersManager.hpp"
#include "context/ContextManager.hpp" #include "context/ContextManager.hpp"
#include "context/TokenUtils.hpp" #include "context/TokenUtils.hpp"
@@ -81,7 +81,7 @@ void InputTokenCounter::rewireToolsChangedConnection()
m_toolsChangedConn = {}; m_toolsChangedConn = {};
const auto providerName = Settings::generalSettings().caProvider(); const auto providerName = Settings::generalSettings().caProvider();
auto *provider = PluginLLMCore::ProvidersManager::instance().getProviderByName(providerName); auto *provider = Providers::ProvidersManager::instance().getProviderByName(providerName);
if (!provider) if (!provider)
return; return;
auto *tm = provider->toolsManager(); auto *tm = provider->toolsManager();
@@ -138,7 +138,7 @@ void InputTokenCounter::recompute()
if (settings.enableChatTools()) { if (settings.enableChatTools()) {
const auto providerName = Settings::generalSettings().caProvider(); const auto providerName = Settings::generalSettings().caProvider();
if (auto *provider = PluginLLMCore::ProvidersManager::instance().getProviderByName( if (auto *provider = Providers::ProvidersManager::instance().getProviderByName(
providerName)) { providerName)) {
if (auto *tm = provider->toolsManager()) { if (auto *tm = provider->toolsManager()) {
const QJsonArray toolDefs = tm->getToolsDefinitions(); const QJsonArray toolDefs = tm->getToolsDefinitions();

View File

Before

Width:  |  Height:  |  Size: 548 B

After

Width:  |  Height:  |  Size: 548 B

View File

Before

Width:  |  Height:  |  Size: 869 B

After

Width:  |  Height:  |  Size: 869 B

View File

Before

Width:  |  Height:  |  Size: 869 B

After

Width:  |  Height:  |  Size: 869 B

View File

Before

Width:  |  Height:  |  Size: 523 B

After

Width:  |  Height:  |  Size: 523 B

View File

Before

Width:  |  Height:  |  Size: 548 B

After

Width:  |  Height:  |  Size: 548 B

View File

Before

Width:  |  Height:  |  Size: 822 B

After

Width:  |  Height:  |  Size: 822 B

View File

Before

Width:  |  Height:  |  Size: 353 B

After

Width:  |  Height:  |  Size: 353 B

View File

Before

Width:  |  Height:  |  Size: 353 B

After

Width:  |  Height:  |  Size: 353 B

View File

Before

Width:  |  Height:  |  Size: 487 B

After

Width:  |  Height:  |  Size: 487 B

View File

Before

Width:  |  Height:  |  Size: 233 B

After

Width:  |  Height:  |  Size: 233 B

View File

Before

Width:  |  Height:  |  Size: 624 B

After

Width:  |  Height:  |  Size: 624 B

View File

Before

Width:  |  Height:  |  Size: 304 B

After

Width:  |  Height:  |  Size: 304 B

View File

Before

Width:  |  Height:  |  Size: 513 B

After

Width:  |  Height:  |  Size: 513 B

View File

Before

Width:  |  Height:  |  Size: 507 B

After

Width:  |  Height:  |  Size: 507 B

View File

Before

Width:  |  Height:  |  Size: 370 B

After

Width:  |  Height:  |  Size: 370 B

View File

Before

Width:  |  Height:  |  Size: 526 B

After

Width:  |  Height:  |  Size: 526 B

View File

Before

Width:  |  Height:  |  Size: 943 B

After

Width:  |  Height:  |  Size: 943 B

View File

Before

Width:  |  Height:  |  Size: 348 B

After

Width:  |  Height:  |  Size: 348 B

View File

Before

Width:  |  Height:  |  Size: 348 B

After

Width:  |  Height:  |  Size: 348 B

View File

Before

Width:  |  Height:  |  Size: 599 B

After

Width:  |  Height:  |  Size: 599 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 370 B

After

Width:  |  Height:  |  Size: 370 B

View File

Before

Width:  |  Height:  |  Size: 962 B

After

Width:  |  Height:  |  Size: 962 B

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 663 B

After

Width:  |  Height:  |  Size: 663 B

View File

Before

Width:  |  Height:  |  Size: 350 B

After

Width:  |  Height:  |  Size: 350 B

View File

Before

Width:  |  Height:  |  Size: 552 B

After

Width:  |  Height:  |  Size: 552 B

View File

Before

Width:  |  Height:  |  Size: 559 B

After

Width:  |  Height:  |  Size: 559 B

View File

Before

Width:  |  Height:  |  Size: 148 B

After

Width:  |  Height:  |  Size: 148 B

View File

Before

Width:  |  Height:  |  Size: 148 B

After

Width:  |  Height:  |  Size: 148 B

Some files were not shown because too many files have changed in this diff Show More