1
0
mirror of synced 2024-11-28 01:20:51 +01:00

feat: Added documentation helper AI

This commit is contained in:
WerWolv 2023-04-10 01:42:53 +02:00
parent 00c9a92977
commit dc77d81e1b
4 changed files with 140 additions and 1 deletions

View File

@ -576,9 +576,10 @@ namespace hex {
}
}
if (!open || !popupDisplaying) {
if (!open && !popupDisplaying) {
sizeSet = false;
popupDisplaying = false;
popupSize = ImVec2(0, 0);
popups.pop_back();
}
}

View 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;
};
}

View File

@ -179,6 +179,7 @@
"hex.builtin.menu.file.quit": "Quit ImHex",
"hex.builtin.menu.file.reload_provider": "Reload Provider",
"hex.builtin.menu.help": "Help",
"hex.builtin.menu.help.ask_for_help": "Ask Documentation...",
"hex.builtin.menu.layout": "Layout",
"hex.builtin.menu.view": "View",
"hex.builtin.menu.view.demo": "Show ImGui Demo",
@ -361,6 +362,10 @@
"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.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.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!",

View File

@ -12,6 +12,7 @@
#include "content/global_actions.hpp"
#include <content/popups/popup_notification.hpp>
#include <content/popups/popup_docs_question.hpp>
#include <wolv/io/file.hpp>
@ -453,6 +454,10 @@ namespace hex::plugin::builtin {
static void createHelpMenu() {
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() {