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;
|
||||
popupDisplaying = false;
|
||||
popupSize = ImVec2(0, 0);
|
||||
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.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!",
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user