Skip to content

Commit

Permalink
feat: [AI] support adding multi LLM
Browse files Browse the repository at this point in the history
optimizing existing features

Log:as title
  • Loading branch information
LiHua000 committed Dec 17, 2024
1 parent d6bffe8 commit c4eca55
Show file tree
Hide file tree
Showing 34 changed files with 1,951 additions and 38 deletions.
2 changes: 2 additions & 0 deletions src/base/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ project(duc-base)
FILE(GLOB_RECURSE PROJECT_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/*.h"
"${CMAKE_CURRENT_SOURCE_DIR}/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/*/*.h"
"${CMAKE_CURRENT_SOURCE_DIR}/*/*.cpp"
)

add_library(
Expand Down
11 changes: 11 additions & 0 deletions src/base/ai/abstractllm.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#include "abstractllm.h"

AbstractLLM::AbstractLLM(QObject *parent)
: QObject(parent)
{
qRegisterMetaType<ResponseState>("ResponseState");
}
45 changes: 45 additions & 0 deletions src/base/ai/abstractllm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#ifndef ABSTRACTLLM_H
#define ABSTRACTLLM_H

#include "conversation.h"

#include <QObject>
#include <QNetworkReply>

class AbstractLLM : public QObject
{
Q_OBJECT
public:
enum ResponseState {
Receiving,
Success,
CutByLength,
Failed,
Canceled
};

explicit AbstractLLM(QObject *parent = nullptr);
virtual ~AbstractLLM() {}

virtual QString modelPath() const = 0;
virtual bool checkValid(QString *errStr) = 0;
virtual QJsonObject create(const Conversation &conversation) = 0;
virtual void request(const QJsonObject &data) = 0;
virtual void request(const QString &prompt) = 0;
virtual void generate(const QString &prompt, const QString &suffix) = 0;
virtual void setTemperature(double temperature) = 0;
virtual void setStream(bool isStream) = 0;
virtual void processResponse(QNetworkReply *reply) = 0;
virtual void cancel() = 0;
virtual void setMaxTokens(int maxToken) = 0;
virtual Conversation *getCurrentConversation() = 0;

signals:
void dataReceived(const QString &data, ResponseState statu);
};

#endif
149 changes: 149 additions & 0 deletions src/base/ai/conversation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#include "conversation.h"

#include <QJsonDocument>
#include <QVariant>

Conversation::Conversation()
{
}

Conversation::~Conversation()
{
}

QString Conversation::conversationLastUserData(const QString &conversation)

Check warning on line 18 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'conversationLastUserData' is never used.

Check warning on line 18 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

The function 'conversationLastUserData' is never used.
{
const QJsonArray &array = QJsonDocument::fromJson(conversation.toUtf8()).array();
if (!array.isEmpty() && array.last()["role"] == "user") {
return array.last()["content"].toString();
}

return conversation;
}

bool Conversation::setSystemData(const QString &data)
{
if (!data.isEmpty()) {
for (auto iter = conversation.begin(); iter != conversation.end(); iter++) {
if (iter->toObject().value("role").toString() == "system")
return false;
}
conversation.insert(0, QJsonObject({ { "role", "system" }, {"content", data} }));
return true;
}
return false;
}

bool Conversation::popSystemData()

Check warning on line 41 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'popSystemData' is never used.

Check warning on line 41 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

The function 'popSystemData' is never used.
{
if (!conversation.isEmpty() && conversation.at(0)["role"].toString() == "system") {
conversation.removeFirst();
return true;
}
return false;
}

bool Conversation::addUserData(const QString &data)
{
if (!data.isEmpty()) {
const QJsonDocument &document = QJsonDocument::fromJson(data.toUtf8());
if (document.isArray()) {
conversation = document.array();
} else {
conversation.push_back(QJsonObject({ { "role", "user" }, {"content", data} }));
}
return true;
}
return false;
}

bool Conversation::popUserData()

Check warning on line 64 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'popUserData' is never used.

Check warning on line 64 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

The function 'popUserData' is never used.
{
if (!conversation.isEmpty() && conversation.last()["role"].toString() == "user") {
conversation.removeLast();
return true;
}
return false;
}

QString Conversation::getLastResponse() const

Check warning on line 73 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'getLastResponse' is never used.

Check warning on line 73 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

The function 'getLastResponse' is never used.
{
if (!conversation.isEmpty() && conversation.last()["role"].toString() == "assistant") {
return conversation.last()["content"].toString();
}
return QString();
}

QByteArray Conversation::getLastByteResponse() const

Check warning on line 81 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'getLastByteResponse' is never used.

Check warning on line 81 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

The function 'getLastByteResponse' is never used.
{
if (!conversation.isEmpty() && conversation.last()["role"].toString() == "assistant") {
return conversation.last()["content"].toVariant().toByteArray();
}
return QByteArray();
}

bool Conversation::popLastResponse()

Check warning on line 89 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'popLastResponse' is never used.

Check warning on line 89 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

The function 'popLastResponse' is never used.
{
if (!conversation.isEmpty() && conversation.last()["role"].toString() == "assistant") {
conversation.removeLast();
return true;
}
return false;
}

QJsonObject Conversation::getLastTools() const

Check warning on line 98 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'getLastTools' is never used.

Check warning on line 98 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

The function 'getLastTools' is never used.
{
if (!conversation.isEmpty() && conversation.last()["role"].toString() == "tools") {
return conversation.last()["content"].toObject();
}

return QJsonObject();
}

bool Conversation::popLastTools()

Check warning on line 107 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'popLastTools' is never used.

Check warning on line 107 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

The function 'popLastTools' is never used.
{
if (!conversation.isEmpty() && conversation.last()["role"].toString() == "tools") {
conversation.removeLast();
return true;
}
return false;
}

bool Conversation::setFunctions(const QJsonArray &functions)
{
this->functions = functions;
return true;
}

QJsonArray Conversation::getConversions() const
{
return conversation;
}

QJsonArray Conversation::getFunctions() const

Check warning on line 127 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'getFunctions' is never used.

Check warning on line 127 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

The function 'getFunctions' is never used.
{
return functions;
}

QJsonArray Conversation::getFunctionTools() const

Check warning on line 132 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'getFunctionTools' is never used.

Check warning on line 132 in src/base/ai/conversation.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

The function 'getFunctionTools' is never used.
{
QJsonArray tools;
for (const QJsonValue &fun : functions) {
QJsonObject tool;
tool["type"] = "function";
tool["function"] = fun;
tools << tool;
}

return tools;
}

void Conversation::clear()
{
conversation = QJsonArray();
functions = QJsonArray();
}
50 changes: 50 additions & 0 deletions src/base/ai/conversation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#ifndef CONVERSATION_H
#define CONVERSATION_H

#include <QJsonObject>
#include <QJsonArray>

class Conversation
{
public:
Conversation();
virtual ~Conversation();

/**
* @brief conversationLastUserData
* @param conversation
* @return
*/
static QString conversationLastUserData(const QString &conversation);

public:
bool setSystemData(const QString &data);
bool popSystemData();

bool addUserData(const QString &data);
bool popUserData();

QString getLastResponse() const;
QByteArray getLastByteResponse() const;
bool popLastResponse();

QJsonObject getLastTools() const;
bool popLastTools();

bool setFunctions(const QJsonArray &functions);
QJsonArray getFunctions() const;
QJsonArray getFunctionTools() const;

QJsonArray getConversions() const;

void clear();
protected:
QJsonArray conversation;
QJsonArray functions;
};

#endif // CONVERSATION_H
1 change: 1 addition & 0 deletions src/plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@ add_subdirectory(commandproxy)
add_subdirectory(codegeex)
add_subdirectory(git)
add_subdirectory(linglong)
add_subdirectory(aimanager)
54 changes: 54 additions & 0 deletions src/plugins/aimanager/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
cmake_minimum_required(VERSION 3.0.2)

set(CMAKE_CXX_STANDARD 17)

project(aimanager)

find_package(duc-base REQUIRED)
find_package(duc-common REQUIRED)
find_package(duc-framework REQUIRED)
find_package(duc-services REQUIRED)
find_package(Dtk COMPONENTS Widget REQUIRED)

set(QtFindModules Core Gui Widgets Concurrent)
foreach(QtModule ${QtFindModules})
find_package(Qt5 COMPONENTS ${QtModule} REQUIRED)
# include qt module private include directors
include_directories(${Qt5${QtModule}_PRIVATE_INCLUDE_DIRS})
# can use target_link_libraries(xxx ${QtUseModules})
list(APPEND QtUseModules "Qt5::${QtModule}")
message("QtModule found ${QtModule} OK!")
endforeach()

FILE(GLOB CODEGEEX_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/*.h"
"${CMAKE_CURRENT_SOURCE_DIR}/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/*/*.h"
"${CMAKE_CURRENT_SOURCE_DIR}/*/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/*.json"
)

add_library(${PROJECT_NAME}
SHARED
${CODEGEEX_FILES}
aimanager.qrc
)

target_link_libraries(${PROJECT_NAME}
duc-framework
duc-base
duc-services
duc-common
${QtUseModules}
${PkgUserModules}
${DtkWidget_LIBRARIES}
)


if(NOT PLUGIN_INSTALL_PATH)
set(PLUGIN_INSTALL_PATH "/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/deepin-unioncode/plugins")
endif()

install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${PLUGIN_INSTALL_PATH})


Loading

0 comments on commit c4eca55

Please sign in to comment.