Files
z-bar-qt/Plugins/ZShell/Llm/llmclient.hpp
zach 0a503bc27c
C++ / fmt (pull_request) Failing after 5s
C++ / build (pull_request) Failing after 10s
C++ / clang-tidy (pull_request) Failing after 10s
JS/TS / fmt (pull_request) Successful in 7s
JS/TS / lint (pull_request) Successful in 8s
Python / static (pull_request) Successful in 27s
Rust / build (pull_request) Successful in 49s
Rust / fmt (pull_request) Successful in 28s
Python / verify (pull_request) Successful in 1m41s
Rust / clippy (pull_request) Successful in 45s
fix: remove unimplemented method
2026-10-18 13:03:25 +02:00

141 lines
4.1 KiB
C++

#pragma once
#include "chatstore.hpp"
#include "tool.hpp"
#include "turn.hpp"
#include <QByteArray>
#include <QJsonArray>
#include <QNetworkAccessManager>
#include <QObject>
#include <QString>
#include <QStringList>
#include <QTimer>
#include <functional>
#include <memory>
class QJsonObject;
class QNetworkReply;
namespace ZShell::llm {
class ChatGeneration;
class ChatSession;
class LlmClient : public QObject {
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_PROPERTY(bool busy READ busy NOTIFY busyChanged)
Q_PROPERTY(QString model READ model NOTIFY modelChanged)
Q_PROPERTY(
QStringList availableModels READ availableModels NOTIFY
availableModelsChanged)
Q_PROPERTY(int contextSize READ contextSize NOTIFY contextSizeChanged)
Q_PROPERTY(
bool toolsEnabled READ toolsEnabled WRITE setToolsEnabled NOTIFY
toolsEnabledChanged)
Q_PROPERTY(
bool sandboxEnabled READ sandboxEnabled WRITE setSandboxEnabled NOTIFY
sandboxEnabledChanged)
Q_PROPERTY(QString serverError READ serverError NOTIFY serverErrorChanged)
Q_PROPERTY(ZShell::llm::ChatStore* chats READ chats CONSTANT)
public:
explicit LlmClient(QObject* parent = nullptr);
~LlmClient() override;
[[nodiscard]] ChatStore* chats() const { return m_store; }
[[nodiscard]] bool busy() const { return m_busy; }
[[nodiscard]] QString model() const { return m_model; }
[[nodiscard]] QStringList availableModels() const {
return m_availableModels;
}
[[nodiscard]] int contextSize() const { return m_tools->contextSize(); }
[[nodiscard]] bool toolsEnabled() const { return m_tools->enabled(); }
[[nodiscard]] bool sandboxEnabled() const {
return m_tools->sandboxEnabled();
}
[[nodiscard]] QString serverError() const { return m_serverError; }
[[nodiscard]] ChatSession* streamingSession() const {
return m_turn ? m_turn->session() : nullptr;
}
void setToolsEnabled(bool value);
void setSandboxEnabled(bool value);
Q_INVOKABLE void selectModel(const QString& id);
Q_INVOKABLE void stop();
Q_INVOKABLE void refreshModels();
void startGeneration(ChatSession* session, ChatGeneration* target);
void approveTools(ZShell::llm::ChatGeneration* generation);
void denyTools(ZShell::llm::ChatGeneration* generation);
void requestTitle(ChatSession* session, const QString& userText);
void requestIcon(ChatSession* session, const QString& userText);
Q_SIGNALS:
void busyChanged();
void modelChanged();
void availableModelsChanged();
void contextSizeChanged();
void toolsEnabledChanged();
void sandboxEnabledChanged();
void serverErrorChanged();
void generationFailed(
ZShell::llm::ChatSession* session, const QString& message);
private:
void sendRound();
void applyToolCallDelta(const QJsonObject& call);
void roundFinished();
void executeAllCalls();
void flushCallResults();
void setApprovalPending(bool value);
void finishPendingCalls(const QString& resultText);
void finishTurn();
void endStream();
void fail(const QString& message);
void handleLine(const QByteArray& line);
void drainBuffer();
void updateTokenUsage(const QJsonObject& data);
void setBusy(bool value);
void setServerError(const QString& value);
void setModel(const QString& value);
void setContextSize(int size);
void probeContextSize(std::function<void()> done = {});
void refreshAllStates();
void shortRequest(
const QString& tag,
const QString& systemPrompt,
const QString& userText,
std::function<void(QString result)> onResult);
static QString completionsPath(
const QString& endpoint, const QString& subpath);
static QString jsonErrorMessage(const QByteArray& body);
static QString serverErrorMessage(
const QByteArray& body, const QString& fallback);
[[nodiscard]] ToolContext toolContext() const;
QNetworkAccessManager m_manager;
ChatStore* m_store = nullptr;
ToolRegistry* m_tools = nullptr;
std::unique_ptr<Turn> m_turn;
QNetworkReply* m_reply = nullptr;
QByteArray m_buffer;
QTimer m_refreshTimer;
QString m_endpoint;
QString m_model;
QStringList m_availableModels;
QString m_serverError;
double m_temperature = 0.7;
bool m_busy = false;
bool m_configEnabled = true;
static constexpr int kMaxToolRounds = 12;
};
} // namespace ZShell::llm