mirror of
https://github.com/Palm1r/QodeAssist.git
synced 2025-06-04 01:28:58 -04:00
Change message history
This commit is contained in:
parent
d7f0cc92e6
commit
fbe363689f
@ -31,6 +31,51 @@
|
|||||||
|
|
||||||
namespace QodeAssist::Chat {
|
namespace QodeAssist::Chat {
|
||||||
|
|
||||||
|
int ChatHistory::estimateTokenCount(const QString &text) const
|
||||||
|
{
|
||||||
|
return text.length() / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatHistory::addMessage(ChatMessage::Role role, const QString &content)
|
||||||
|
{
|
||||||
|
int tokenCount = estimateTokenCount(content);
|
||||||
|
m_messages.append({role, content, tokenCount});
|
||||||
|
m_totalTokens += tokenCount;
|
||||||
|
trim();
|
||||||
|
}
|
||||||
|
void ChatHistory::clear()
|
||||||
|
{
|
||||||
|
m_messages.clear();
|
||||||
|
m_totalTokens = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<ChatMessage> ChatHistory::getMessages() const
|
||||||
|
{
|
||||||
|
return m_messages;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ChatHistory::getSystemPrompt() const
|
||||||
|
{
|
||||||
|
return m_systemPrompt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatHistory::setSystemPrompt(const QString &prompt)
|
||||||
|
{
|
||||||
|
m_systemPrompt = prompt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatHistory::trim()
|
||||||
|
{
|
||||||
|
while (m_messages.size() > MAX_HISTORY_SIZE || m_totalTokens > MAX_TOKENS) {
|
||||||
|
if (!m_messages.isEmpty()) {
|
||||||
|
m_totalTokens -= m_messages.first().tokenCount;
|
||||||
|
m_messages.removeFirst();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ChatClientInterface::ChatClientInterface(QObject *parent)
|
ChatClientInterface::ChatClientInterface(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_requestHandler(new LLMRequestHandler(this))
|
, m_requestHandler(new LLMRequestHandler(this))
|
||||||
@ -51,15 +96,10 @@ ChatClientInterface::ChatClientInterface(QObject *parent)
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// QJsonObject systemMessage;
|
m_chatHistory.setSystemPrompt("You are a helpful C++ and QML programming assistant.");
|
||||||
// systemMessage["role"] = "system";
|
|
||||||
// systemMessage["content"] = "You are a helpful C++ and QML programming assistant.";
|
|
||||||
// m_chatHistory.append(systemMessage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatClientInterface::~ChatClientInterface()
|
ChatClientInterface::~ChatClientInterface() = default;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatClientInterface::sendMessage(const QString &message)
|
void ChatClientInterface::sendMessage(const QString &message)
|
||||||
{
|
{
|
||||||
@ -79,14 +119,11 @@ void ChatClientInterface::sendMessage(const QString &message)
|
|||||||
QJsonObject providerRequest;
|
QJsonObject providerRequest;
|
||||||
providerRequest["model"] = Settings::generalSettings().chatModelName();
|
providerRequest["model"] = Settings::generalSettings().chatModelName();
|
||||||
providerRequest["stream"] = true;
|
providerRequest["stream"] = true;
|
||||||
|
providerRequest["messages"] = prepareMessagesForRequest();
|
||||||
providerRequest["messages"] = m_chatHistory;
|
|
||||||
|
|
||||||
chatTemplate->prepareRequest(providerRequest, context);
|
chatTemplate->prepareRequest(providerRequest, context);
|
||||||
chatProvider->prepareRequest(providerRequest);
|
chatProvider->prepareRequest(providerRequest);
|
||||||
|
|
||||||
m_chatHistory = providerRequest["messages"].toArray();
|
|
||||||
|
|
||||||
LLMConfig config;
|
LLMConfig config;
|
||||||
config.requestType = RequestType::Chat;
|
config.requestType = RequestType::Chat;
|
||||||
config.provider = chatProvider;
|
config.provider = chatProvider;
|
||||||
@ -99,18 +136,22 @@ void ChatClientInterface::sendMessage(const QString &message)
|
|||||||
request["id"] = QUuid::createUuid().toString();
|
request["id"] = QUuid::createUuid().toString();
|
||||||
|
|
||||||
m_accumulatedResponse.clear();
|
m_accumulatedResponse.clear();
|
||||||
m_pendingMessage = message;
|
m_chatHistory.addMessage(ChatMessage::Role::User, message);
|
||||||
m_requestHandler->sendLLMRequest(config, request);
|
m_requestHandler->sendLLMRequest(config, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatClientInterface::clearMessages()
|
void ChatClientInterface::clearMessages()
|
||||||
{
|
{
|
||||||
m_chatHistory = {};
|
m_chatHistory.clear();
|
||||||
m_accumulatedResponse.clear();
|
m_accumulatedResponse.clear();
|
||||||
m_pendingMessage.clear();
|
|
||||||
logMessage("Chat history cleared");
|
logMessage("Chat history cleared");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<ChatMessage> ChatClientInterface::getChatHistory() const
|
||||||
|
{
|
||||||
|
return m_chatHistory.getMessages();
|
||||||
|
}
|
||||||
|
|
||||||
void ChatClientInterface::handleLLMResponse(const QString &response, bool isComplete)
|
void ChatClientInterface::handleLLMResponse(const QString &response, bool isComplete)
|
||||||
{
|
{
|
||||||
m_accumulatedResponse += response;
|
m_accumulatedResponse += response;
|
||||||
@ -119,42 +160,33 @@ void ChatClientInterface::handleLLMResponse(const QString &response, bool isComp
|
|||||||
logMessage("Message completed. Final response: " + m_accumulatedResponse);
|
logMessage("Message completed. Final response: " + m_accumulatedResponse);
|
||||||
emit messageReceived(m_accumulatedResponse.trimmed());
|
emit messageReceived(m_accumulatedResponse.trimmed());
|
||||||
|
|
||||||
QJsonObject assistantMessage;
|
m_chatHistory.addMessage(ChatMessage::Role::Assistant, m_accumulatedResponse.trimmed());
|
||||||
assistantMessage["role"] = "assistant";
|
|
||||||
assistantMessage["content"] = m_accumulatedResponse.trimmed();
|
|
||||||
m_chatHistory.append(assistantMessage);
|
|
||||||
|
|
||||||
m_pendingMessage.clear();
|
|
||||||
m_accumulatedResponse.clear();
|
m_accumulatedResponse.clear();
|
||||||
|
|
||||||
trimChatHistory();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatClientInterface::trimChatHistory()
|
QJsonArray ChatClientInterface::prepareMessagesForRequest() const
|
||||||
{
|
{
|
||||||
int maxTokens = 4000;
|
QJsonArray messages;
|
||||||
int totalTokens = 0;
|
|
||||||
QJsonArray newHistory;
|
|
||||||
|
|
||||||
if (!m_chatHistory.isEmpty()
|
messages.append(QJsonObject{{"role", "system"}, {"content", m_chatHistory.getSystemPrompt()}});
|
||||||
&& m_chatHistory.first().toObject()["role"].toString() == "system") {
|
|
||||||
newHistory.append(m_chatHistory.first());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = m_chatHistory.size() - 1; i >= 0; --i) {
|
for (const auto &message : m_chatHistory.getMessages()) {
|
||||||
QJsonObject message = m_chatHistory[i].toObject();
|
QString role;
|
||||||
int messageTokens = message["content"].toString().length() / 4;
|
switch (message.role) {
|
||||||
|
case ChatMessage::Role::User:
|
||||||
if (totalTokens + messageTokens > maxTokens) {
|
role = "user";
|
||||||
break;
|
break;
|
||||||
|
case ChatMessage::Role::Assistant:
|
||||||
|
role = "assistant";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
messages.append(QJsonObject{{"role", role}, {"content", message.content}});
|
||||||
newHistory.prepend(message);
|
|
||||||
totalTokens += messageTokens;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_chatHistory = newHistory;
|
return messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace QodeAssist::Chat
|
} // namespace QodeAssist::Chat
|
||||||
|
@ -20,12 +20,41 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QtCore/qjsonarray.h>
|
#include <QString>
|
||||||
|
#include <QVector>
|
||||||
#include "QodeAssistData.hpp"
|
#include "QodeAssistData.hpp"
|
||||||
#include "core/LLMRequestHandler.hpp"
|
#include "core/LLMRequestHandler.hpp"
|
||||||
|
|
||||||
namespace QodeAssist::Chat {
|
namespace QodeAssist::Chat {
|
||||||
|
|
||||||
|
struct ChatMessage
|
||||||
|
{
|
||||||
|
enum class Role { System, User, Assistant };
|
||||||
|
Role role;
|
||||||
|
QString content;
|
||||||
|
int tokenCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ChatHistory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void addMessage(ChatMessage::Role role, const QString &content);
|
||||||
|
void clear();
|
||||||
|
QVector<ChatMessage> getMessages() const;
|
||||||
|
QString getSystemPrompt() const;
|
||||||
|
void setSystemPrompt(const QString &prompt);
|
||||||
|
void trim();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector<ChatMessage> m_messages;
|
||||||
|
QString m_systemPrompt;
|
||||||
|
int m_totalTokens = 0;
|
||||||
|
static const int MAX_HISTORY_SIZE = 50;
|
||||||
|
static const int MAX_TOKENS = 4000;
|
||||||
|
|
||||||
|
int estimateTokenCount(const QString &text) const;
|
||||||
|
};
|
||||||
|
|
||||||
class ChatClientInterface : public QObject
|
class ChatClientInterface : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -36,6 +65,7 @@ public:
|
|||||||
|
|
||||||
void sendMessage(const QString &message);
|
void sendMessage(const QString &message);
|
||||||
void clearMessages();
|
void clearMessages();
|
||||||
|
QVector<ChatMessage> getChatHistory() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void messageReceived(const QString &message);
|
void messageReceived(const QString &message);
|
||||||
@ -43,12 +73,11 @@ signals:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void handleLLMResponse(const QString &response, bool isComplete);
|
void handleLLMResponse(const QString &response, bool isComplete);
|
||||||
void trimChatHistory();
|
QJsonArray prepareMessagesForRequest() const;
|
||||||
|
|
||||||
LLMRequestHandler *m_requestHandler;
|
LLMRequestHandler *m_requestHandler;
|
||||||
QString m_accumulatedResponse;
|
QString m_accumulatedResponse;
|
||||||
QString m_pendingMessage;
|
ChatHistory m_chatHistory;
|
||||||
QJsonArray m_chatHistory;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QodeAssist::Chat
|
} // namespace QodeAssist::Chat
|
||||||
|
Loading…
x
Reference in New Issue
Block a user