mirror of
https://github.com/Palm1r/QodeAssist.git
synced 2025-10-08 04:54:57 -04:00
Feat: Add Claude tools support to plugin (#231)
* feat: Add settings for handle using tools in chat * feat: Add Claude tools support * fix: Add ai ignore to read project files list tool * fix: Add ai ignore to read project file by name tool * fix: Add ai ignore to read current opened files tool
This commit is contained in:
@ -19,6 +19,7 @@ add_library(LLMCore STATIC
|
||||
SSEBuffer.hpp SSEBuffer.cpp
|
||||
BaseTool.hpp
|
||||
BaseTool.cpp
|
||||
ContentBlocks.hpp
|
||||
)
|
||||
|
||||
target_link_libraries(LLMCore
|
||||
|
140
llmcore/ContentBlocks.hpp
Normal file
140
llmcore/ContentBlocks.hpp
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (C) 2025 Petr Mironychev
|
||||
*
|
||||
* This file is part of QodeAssist.
|
||||
*
|
||||
* QodeAssist is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* QodeAssist is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with QodeAssist. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QHash>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
namespace QodeAssist::LLMCore {
|
||||
|
||||
enum class MessageState { Building, Complete, RequiresToolExecution, Final };
|
||||
|
||||
enum class ProviderFormat { Claude, OpenAI };
|
||||
|
||||
class ContentBlock : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ContentBlock(QObject *parent = nullptr)
|
||||
: QObject(parent)
|
||||
{}
|
||||
virtual ~ContentBlock() = default;
|
||||
virtual QString type() const = 0;
|
||||
virtual QJsonValue toJson(ProviderFormat format) const = 0;
|
||||
};
|
||||
|
||||
class TextContent : public ContentBlock
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TextContent(const QString &text = QString())
|
||||
: ContentBlock()
|
||||
, m_text(text)
|
||||
{}
|
||||
|
||||
QString type() const override { return "text"; }
|
||||
QString text() const { return m_text; }
|
||||
void appendText(const QString &text) { m_text += text; }
|
||||
void setText(const QString &text) { m_text = text; }
|
||||
|
||||
QJsonValue toJson(ProviderFormat format) const override
|
||||
{
|
||||
Q_UNUSED(format);
|
||||
return QJsonObject{{"type", "text"}, {"text", m_text}};
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_text;
|
||||
};
|
||||
|
||||
class ToolUseContent : public ContentBlock
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ToolUseContent(const QString &id, const QString &name, const QJsonObject &input = QJsonObject())
|
||||
: ContentBlock()
|
||||
, m_id(id)
|
||||
, m_name(name)
|
||||
, m_input(input)
|
||||
{}
|
||||
|
||||
QString type() const override { return "tool_use"; }
|
||||
QString id() const { return m_id; }
|
||||
QString name() const { return m_name; }
|
||||
QJsonObject input() const { return m_input; }
|
||||
void setInput(const QJsonObject &input) { m_input = input; }
|
||||
|
||||
QJsonValue toJson(ProviderFormat format) const override
|
||||
{
|
||||
if (format == ProviderFormat::Claude) {
|
||||
return QJsonObject{
|
||||
{"type", "tool_use"}, {"id", m_id}, {"name", m_name}, {"input", m_input}};
|
||||
} else { // OpenAI
|
||||
QJsonDocument doc(m_input);
|
||||
return QJsonObject{
|
||||
{"id", m_id},
|
||||
{"type", "function"},
|
||||
{"function",
|
||||
QJsonObject{
|
||||
{"name", m_name},
|
||||
{"arguments", QString::fromUtf8(doc.toJson(QJsonDocument::Compact))}}}};
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_id;
|
||||
QString m_name;
|
||||
QJsonObject m_input;
|
||||
};
|
||||
|
||||
class ToolResultContent : public ContentBlock
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ToolResultContent(const QString &toolUseId, const QString &result)
|
||||
: ContentBlock()
|
||||
, m_toolUseId(toolUseId)
|
||||
, m_result(result)
|
||||
{}
|
||||
|
||||
QString type() const override { return "tool_result"; }
|
||||
QString toolUseId() const { return m_toolUseId; }
|
||||
QString result() const { return m_result; }
|
||||
|
||||
QJsonValue toJson(ProviderFormat format) const override
|
||||
{
|
||||
if (format == ProviderFormat::Claude) {
|
||||
return QJsonObject{
|
||||
{"type", "tool_result"}, {"tool_use_id", m_toolUseId}, {"content", m_result}};
|
||||
} else { // OpenAI
|
||||
return QJsonObject{{"role", "tool"}, {"tool_call_id", m_toolUseId}, {"content", m_result}};
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_toolUseId;
|
||||
QString m_result;
|
||||
};
|
||||
|
||||
} // namespace QodeAssist::LLMCore
|
@ -12,6 +12,11 @@ Provider::Provider(QObject *parent)
|
||||
connect(m_httpClient, &HttpClient::requestFinished, this, &Provider::onRequestFinished);
|
||||
}
|
||||
|
||||
void Provider::cancelRequest(const RequestID &requestId)
|
||||
{
|
||||
m_httpClient->cancelRequest(requestId);
|
||||
}
|
||||
|
||||
HttpClient *Provider::httpClient() const
|
||||
{
|
||||
return m_httpClient;
|
||||
|
@ -63,7 +63,9 @@ public:
|
||||
virtual void sendRequest(const RequestID &requestId, const QUrl &url, const QJsonObject &payload)
|
||||
= 0;
|
||||
|
||||
virtual bool supportsTools() { return false; };
|
||||
virtual bool supportsTools() const { return false; };
|
||||
|
||||
virtual void cancelRequest(const RequestID &requestId);
|
||||
|
||||
HttpClient *httpClient() const;
|
||||
|
||||
|
Reference in New Issue
Block a user