Skip to content

Commit

Permalink
feat: [aiManager] add interface
Browse files Browse the repository at this point in the history
1.event when LLM changed
2.modelname
3.LLM`s idle state to description LLM can send request or not

Log: as title
  • Loading branch information
LiHua000 committed Dec 26, 2024
1 parent 983b499 commit 09c9fbe
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/base/ai/abstractllm.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class AbstractLLM : public QObject
explicit AbstractLLM(QObject *parent = nullptr);
virtual ~AbstractLLM() {}

virtual QString modelName() const = 0;
virtual QString modelPath() const = 0;
virtual bool checkValid(QString *errStr) = 0;
virtual QJsonObject create(const Conversation &conversation) = 0;
Expand All @@ -37,6 +38,7 @@ class AbstractLLM : public QObject
virtual void cancel() = 0;
virtual void setMaxTokens(int maxToken) = 0;
virtual Conversation *getCurrentConversation() = 0;
virtual bool isIdle() = 0;

signals:
void dataReceived(const QString &data, ResponseState statu);
Expand Down
3 changes: 3 additions & 0 deletions src/common/util/eventdefinitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ OPI_OBJECT(session,
OPI_INTERFACE(sessionRenamed, "oldName", "newName")
OPI_INTERFACE(sessionRemoved, "session")
)
OPI_OBJECT(ai,
OPI_INTERFACE(LLMChanged)
)

struct AnalysedData
{
Expand Down
15 changes: 14 additions & 1 deletion src/plugins/aimanager/aimanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "openai/openaicompatiblellm.h"
#include "services/option/optionmanager.h"

Check warning on line 8 in src/plugins/aimanager/aimanager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "services/option/optionmanager.h" not found.

Check warning on line 8 in src/plugins/aimanager/aimanager.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: "services/option/optionmanager.h" not found.
#include "option/detailwidget.h"
#include "common/util/eventdefinitions.h"

Check warning on line 10 in src/plugins/aimanager/aimanager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "common/util/eventdefinitions.h" not found.

Check warning on line 10 in src/plugins/aimanager/aimanager.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: "common/util/eventdefinitions.h" not found.

#include <QMap>

Check warning on line 12 in src/plugins/aimanager/aimanager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QMap> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 12 in src/plugins/aimanager/aimanager.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QMap> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Expand Down Expand Up @@ -83,10 +84,22 @@ void AiManager::removeModel(const LLMInfo &info)

void AiManager::readLLMFromOption()
{
auto currentModels = d->models;
bool changed = false;
d->models.clear();

QMap<QString, QVariant> map = OptionManager::getInstance()->getValue(kCATEGORY_CUSTOMMODELS, kCATEGORY_OPTIONKEY).toMap();
auto LLMs = map.value(kCATEGORY_CUSTOMMODELS);
if (LLMs.toList().size() != currentModels.size())
changed = true;

for (auto llmInfo : LLMs.toList()) {
appendModel(LLMInfo::fromVariantMap(llmInfo.toMap()));
LLMInfo info = LLMInfo::fromVariantMap(llmInfo.toMap());
if (!currentModels.contains(info))
changed = true;
appendModel(info);
}

if (changed)
ai.LLMChanged();
}
65 changes: 65 additions & 0 deletions src/plugins/aimanager/openai/openaicompatibleconversation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ QJsonObject OpenAiCompatibleConversation::parseContentString(const QString &cont
QRegularExpressionMatchIterator iter = regex.globalMatch(content);

Check warning on line 19 in src/plugins/aimanager/openai/openaicompatibleconversation.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Local variable 'iter' shadows outer variable

Check warning on line 19 in src/plugins/aimanager/openai/openaicompatibleconversation.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Local variable 'iter' shadows outer variable

QString finishReason = "";
QJsonObject functionCall;
QMap<int, QJsonObject> toolCallMaps;

while (iter.hasNext()) {
QRegularExpressionMatch match = iter.next();
QString matchString = match.captured(0);
Expand All @@ -42,6 +45,52 @@ QJsonObject OpenAiCompatibleConversation::parseContentString(const QString &cont
const QString &deltaData = delta["content"].toString();
deltacontent += deltaData;
}
if (delta.contains("function_call")) {
const QJsonObject &function_call = delta.value("function_call").toObject();
if (function_call.contains("name")) {
functionCall["name"] = functionCall["name"].toString() + function_call.value("name").toString();
}

if (function_call.contains("arguments")) {
functionCall["arguments"] = functionCall["arguments"].toString() + function_call.value("arguments").toString();
}
}

if (delta.contains("tool_calls")) {
const QJsonArray &tool_calls = delta.value("tool_calls").toArray();
for (const QJsonValue &tool_call : tool_calls) {
const QJsonObject &toolCallObj = tool_call.toObject();

int index = toolCallObj["index"].toInt();
if (!toolCallMaps[index].contains("function")) {
toolCallMaps[index]["function"] = QJsonObject();
}

toolCallMaps[index]["index"] = index;

if (toolCallObj.contains("id")) {
toolCallMaps[index]["id"] = toolCallObj.value("id");
}

if (toolCallObj.contains("type")) {
toolCallMaps[index]["type"] = toolCallObj.value("type");
}

if (toolCallObj.contains("function")) {
QJsonObject toolFun = toolCallMaps[index]["function"].toObject();
const QJsonObject &tmpToolFun = toolCallObj.value("function").toObject();
if (tmpToolFun.contains("name")) {
toolFun["name"] = toolFun["name"].toString() + tmpToolFun.value("name").toString();
}

if (tmpToolFun.contains("arguments")) {
toolFun["arguments"] = toolFun["arguments"].toString() + tmpToolFun.value("arguments").toString();
}

toolCallMaps[index]["function"] = toolFun;
}
}
}
} else if (cj.contains("text")) {
deltacontent += cj["text"].toString();
}
Expand All @@ -55,6 +104,22 @@ QJsonObject OpenAiCompatibleConversation::parseContentString(const QString &cont
response["content"] = deltacontent;
}

QJsonObject tools;
if (!functionCall.isEmpty()) {
tools["function_call"] = functionCall;
response["tools"] = tools;
}

QJsonArray toolCalls;
for (auto iter = toolCallMaps.begin(); iter != toolCallMaps.end(); iter++) {
toolCalls << iter.value();
}

if (!toolCalls.isEmpty()) {
tools["tool_calls"] = toolCalls;
response["tools"] = tools;
}

if (!finishReason.isEmpty())
response["finish_reason"] = finishReason;

Expand Down
13 changes: 13 additions & 0 deletions src/plugins/aimanager/openai/openaicompatiblellm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ OpenAiCompatibleLLM::~OpenAiCompatibleLLM()
delete d;
}

QString OpenAiCompatibleLLM::modelName() const

Check warning on line 122 in src/plugins/aimanager/openai/openaicompatiblellm.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'modelName' is never used.

Check warning on line 122 in src/plugins/aimanager/openai/openaicompatiblellm.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

The function 'modelName' is never used.
{
return d->modelName;
}

QString OpenAiCompatibleLLM::modelPath() const
{
return d->modelPath;
Expand Down Expand Up @@ -196,6 +201,9 @@ QJsonObject OpenAiCompatibleLLM::create(const Conversation &conversation)

void OpenAiCompatibleLLM::request(const QJsonObject &data)
{
if (d->waitingResponse)
return;

QByteArray body = QJsonDocument(data).toJson();
d->httpResult.clear();
d->waitingResponse = true;
Expand Down Expand Up @@ -339,3 +347,8 @@ void OpenAiCompatibleLLM::setMaxTokens(int maxTokens)
{
d->maxTokens = maxTokens;
}

bool OpenAiCompatibleLLM::isIdle()

Check warning on line 351 in src/plugins/aimanager/openai/openaicompatiblellm.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'isIdle' is never used.

Check warning on line 351 in src/plugins/aimanager/openai/openaicompatiblellm.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

The function 'isIdle' is never used.
{
return !d->waitingResponse;
}
2 changes: 2 additions & 0 deletions src/plugins/aimanager/openai/openaicompatiblellm.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class OpenAiCompatibleLLM : public AbstractLLM
void setModelPath(const QString &path);
void setApiKey(const QString &apiKey);

QString modelName() const override;
QString modelPath() const override;
bool checkValid(QString *errStr) override;
QJsonObject create(const Conversation &conversation) override;
Expand All @@ -31,6 +32,7 @@ class OpenAiCompatibleLLM : public AbstractLLM
void processResponse(QNetworkReply *reply) override;
void cancel() override;
void setMaxTokens(int maxTokens) override;
bool isIdle() override;

signals:
void requstCancel();
Expand Down

0 comments on commit 09c9fbe

Please sign in to comment.