feat: Added documentation helper AI
This commit is contained in:
parent
00c9a92977
commit
dc77d81e1b
@ -576,9 +576,10 @@ namespace hex {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!open || !popupDisplaying) {
|
if (!open && !popupDisplaying) {
|
||||||
sizeSet = false;
|
sizeSet = false;
|
||||||
popupDisplaying = false;
|
popupDisplaying = false;
|
||||||
|
popupSize = ImVec2(0, 0);
|
||||||
popups.pop_back();
|
popups.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
128
plugins/builtin/include/content/popups/popup_docs_question.hpp
Normal file
128
plugins/builtin/include/content/popups/popup_docs_question.hpp
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
#include <hex/ui/popup.hpp>
|
||||||
|
|
||||||
|
#include <hex/ui/imgui_imhex_extensions.h>
|
||||||
|
|
||||||
|
#include <hex/api/localization.hpp>
|
||||||
|
#include <hex/helpers/http_requests.hpp>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace hex::plugin::builtin {
|
||||||
|
|
||||||
|
class PopupDocsQuestion : public Popup<PopupDocsQuestion> {
|
||||||
|
public:
|
||||||
|
PopupDocsQuestion()
|
||||||
|
: hex::Popup<PopupDocsQuestion>("hex.builtin.popup.docs_question.title", true, true) { }
|
||||||
|
|
||||||
|
enum class TextBlockType {
|
||||||
|
Text,
|
||||||
|
Code
|
||||||
|
};
|
||||||
|
|
||||||
|
void drawContent() override {
|
||||||
|
ImGui::PushItemWidth(600_scaled);
|
||||||
|
ImGui::BeginDisabled(this->m_requestTask.isRunning());
|
||||||
|
if (ImGui::InputText("##input", this->m_inputBuffer, ImGuiInputTextFlags_EnterReturnsTrue)) {
|
||||||
|
this->executeQuery();
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
|
||||||
|
if (ImGui::BeginChild("##answer", scaled(ImVec2(600, 350)), true, ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
|
||||||
|
if (!this->m_requestTask.isRunning()) {
|
||||||
|
if (this->m_answer.empty()) {
|
||||||
|
if (this->m_noAnswer)
|
||||||
|
ImGui::TextFormattedCentered("{}", "hex.builtin.popup.docs_question.no_answer"_lang);
|
||||||
|
else
|
||||||
|
ImGui::TextFormattedCentered("{}", "hex.builtin.popup.docs_question.prompt"_lang);
|
||||||
|
} else {
|
||||||
|
for (auto &[type, text] : this->m_answer) {
|
||||||
|
switch (type) {
|
||||||
|
case TextBlockType::Text:
|
||||||
|
ImGui::TextFormattedWrapped("{}", text);
|
||||||
|
break;
|
||||||
|
case TextBlockType::Code:
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetStyle().Colors[ImGuiCol_WindowBg]);
|
||||||
|
auto textWidth = 400_scaled - ImGui::GetStyle().FramePadding.x * 4 - ImGui::GetStyle().ScrollbarSize;
|
||||||
|
auto textHeight = ImGui::CalcTextSize(text.c_str(), nullptr, false, textWidth).y + ImGui::GetStyle().FramePadding.y * 6;
|
||||||
|
if (ImGui::BeginChild("##code", ImVec2(textWidth, textHeight), true)) {
|
||||||
|
ImGui::TextFormattedWrapped("{}", text);
|
||||||
|
ImGui::EndChild();
|
||||||
|
}
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ImGui::TextFormattedCentered("{}", "hex.builtin.popup.docs_question.thinking"_lang);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndChild();
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] ImGuiWindowFlags getFlags() const override {
|
||||||
|
return ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void executeQuery() {
|
||||||
|
this->m_requestTask = TaskManager::createBackgroundTask("Query Docs", [this, input = this->m_inputBuffer](Task &) {
|
||||||
|
this->m_noAnswer = false;
|
||||||
|
for (auto space : { "xj7sbzGbHH260vbpZOu1", "WZzDdGjxmgMSIE3xly6o" }) {
|
||||||
|
this->m_answer.clear();
|
||||||
|
|
||||||
|
auto request = HttpRequest("POST", hex::format("https://api.gitbook.com/v1/spaces/{}/search/ask", space));
|
||||||
|
|
||||||
|
request.setBody(hex::format(R"({{ "query": "{}" }})", input));
|
||||||
|
request.addHeader("Content-Type", "application/json");
|
||||||
|
|
||||||
|
auto response = request.execute().get();
|
||||||
|
if (!response.isSuccess())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
try {
|
||||||
|
auto json = nlohmann::json::parse(response.getData());
|
||||||
|
if (!json.contains("answer"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto answer = json["answer"]["text"].get<std::string>();
|
||||||
|
if (answer.empty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
auto blocks = wolv::util::splitString(answer, "```");
|
||||||
|
for (auto &block : blocks) {
|
||||||
|
if (block.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
block = wolv::util::trim(block);
|
||||||
|
|
||||||
|
if (block.starts_with("rust\n")) {
|
||||||
|
block = block.substr(5);
|
||||||
|
this->m_answer.emplace_back(TextBlockType::Code, block);
|
||||||
|
} else if (block.starts_with("cpp\n")) {
|
||||||
|
block = block.substr(4);
|
||||||
|
this->m_answer.emplace_back(TextBlockType::Code, block);
|
||||||
|
} else {
|
||||||
|
this->m_answer.emplace_back(TextBlockType::Text, block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(...) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->m_noAnswer = this->m_answer.empty();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_inputBuffer;
|
||||||
|
std::vector<std::pair<TextBlockType, std::string>> m_answer;
|
||||||
|
TaskHolder m_requestTask;
|
||||||
|
bool m_noAnswer = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -179,6 +179,7 @@
|
|||||||
"hex.builtin.menu.file.quit": "Quit ImHex",
|
"hex.builtin.menu.file.quit": "Quit ImHex",
|
||||||
"hex.builtin.menu.file.reload_provider": "Reload Provider",
|
"hex.builtin.menu.file.reload_provider": "Reload Provider",
|
||||||
"hex.builtin.menu.help": "Help",
|
"hex.builtin.menu.help": "Help",
|
||||||
|
"hex.builtin.menu.help.ask_for_help": "Ask Documentation...",
|
||||||
"hex.builtin.menu.layout": "Layout",
|
"hex.builtin.menu.layout": "Layout",
|
||||||
"hex.builtin.menu.view": "View",
|
"hex.builtin.menu.view": "View",
|
||||||
"hex.builtin.menu.view.demo": "Show ImGui Demo",
|
"hex.builtin.menu.view.demo": "Show ImGui Demo",
|
||||||
@ -361,6 +362,10 @@
|
|||||||
"hex.builtin.pl_visualizer.3d.scale": "Scale",
|
"hex.builtin.pl_visualizer.3d.scale": "Scale",
|
||||||
"hex.builtin.popup.close_provider.desc": "There are unsaved changes made to this Provider\nthat haven't been saved to a Project yet.\n\nAre you sure you want to close it?",
|
"hex.builtin.popup.close_provider.desc": "There are unsaved changes made to this Provider\nthat haven't been saved to a Project yet.\n\nAre you sure you want to close it?",
|
||||||
"hex.builtin.popup.close_provider.title": "Close Provider?",
|
"hex.builtin.popup.close_provider.title": "Close Provider?",
|
||||||
|
"hex.builtin.popup.docs_question.title": "Documentation query",
|
||||||
|
"hex.builtin.popup.docs_question.no_answer": "The documentation didn't have an answer for this question",
|
||||||
|
"hex.builtin.popup.docs_question.prompt": "Ask the documentation AI for help!",
|
||||||
|
"hex.builtin.popup.docs_question.thinking": "Thinking...",
|
||||||
"hex.builtin.popup.error.create": "Failed to create new file!",
|
"hex.builtin.popup.error.create": "Failed to create new file!",
|
||||||
"hex.builtin.popup.error.file_dialog.common": "An error occurred while opening the file browser: {}",
|
"hex.builtin.popup.error.file_dialog.common": "An error occurred while opening the file browser: {}",
|
||||||
"hex.builtin.popup.error.file_dialog.portal": "There was an error while opening the file browser: {}.\nThis might be caused by your system not having a xdg-desktop-portal backend installed correctly.\n\nOn KDE, it's xdg-desktop-portal-kde.\nOn Gnome it's xdg-desktop-portal-gnome.\nOn wlroots it's xdg-desktop-portal-wlr.\nOtherwise, you can try to use xdg-desktop-portal-gtk.\n\nReboot your system after installing it.\n\nIf the file browser still doesn't work after this, submit an issue at https://github.com/WerWolv/ImHex/issues\n\nIn the meantime files can still be opened by dragging them onto the ImHex window!",
|
"hex.builtin.popup.error.file_dialog.portal": "There was an error while opening the file browser: {}.\nThis might be caused by your system not having a xdg-desktop-portal backend installed correctly.\n\nOn KDE, it's xdg-desktop-portal-kde.\nOn Gnome it's xdg-desktop-portal-gnome.\nOn wlroots it's xdg-desktop-portal-wlr.\nOtherwise, you can try to use xdg-desktop-portal-gtk.\n\nReboot your system after installing it.\n\nIf the file browser still doesn't work after this, submit an issue at https://github.com/WerWolv/ImHex/issues\n\nIn the meantime files can still be opened by dragging them onto the ImHex window!",
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "content/global_actions.hpp"
|
#include "content/global_actions.hpp"
|
||||||
#include <content/popups/popup_notification.hpp>
|
#include <content/popups/popup_notification.hpp>
|
||||||
|
#include <content/popups/popup_docs_question.hpp>
|
||||||
|
|
||||||
#include <wolv/io/file.hpp>
|
#include <wolv/io/file.hpp>
|
||||||
|
|
||||||
@ -453,6 +454,10 @@ namespace hex::plugin::builtin {
|
|||||||
|
|
||||||
static void createHelpMenu() {
|
static void createHelpMenu() {
|
||||||
ContentRegistry::Interface::registerMainMenuItem("hex.builtin.menu.help", 5000);
|
ContentRegistry::Interface::registerMainMenuItem("hex.builtin.menu.help", 5000);
|
||||||
|
|
||||||
|
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.help", "hex.builtin.menu.help.ask_for_help" }, 5000, CTRLCMD + SHIFT + Keys::D, [] {
|
||||||
|
PopupDocsQuestion::open();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerMainMenuEntries() {
|
void registerMainMenuEntries() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user