feat: Add support for executing patterns using MCP

This commit is contained in:
WerWolv
2025-12-26 22:32:48 +01:00
parent d6d70ca076
commit ba7e789a80
7 changed files with 206 additions and 10 deletions

View File

@@ -20,8 +20,17 @@ namespace hex::plugin::builtin {
ImHexApi::Provider::openProvider(provider);
}
return mcp::TextContent {
.text = "File opened"
nlohmann::json result = {
{ "handle", provider->getID() },
{ "name", provider->getName() },
{ "type", provider->getTypeName().get() },
{ "size", provider->getSize() },
{ "is_writable", provider->isWritable() }
};
return mcp::StructuredContent {
.text = result.dump(),
.data = result
};
});
@@ -59,7 +68,9 @@ namespace hex::plugin::builtin {
}
}
nlohmann::json result = { "selected_handle", ImHexApi::Provider::get()->getID() };
nlohmann::json result = {
{ "selected_handle", ImHexApi::Provider::get()->getID() }
};
return mcp::StructuredContent {
.text = result.dump(),
.data = result
@@ -79,9 +90,9 @@ namespace hex::plugin::builtin {
auto base64 = crypt::encode64(buffer);
nlohmann::json result = {
"handle", provider->getID(),
"data", std::string(base64.begin(), base64.end()),
"data_size", buffer.size()
{ "handle", provider->getID() },
{ "data", std::string(base64.begin(), base64.end()) },
{ "data_size", buffer.size() }
};
return mcp::StructuredContent {
.text = result.dump(),

View File

@@ -43,9 +43,11 @@
#include <wolv/utils/lock.hpp>
#include <fonts/fonts.hpp>
#include <hex/api/content_registry/communication_interface.hpp>
#include <hex/api/events/requests_gui.hpp>
#include <hex/helpers/menu_items.hpp>
#include <hex/helpers/logger.hpp>
#include <romfs/romfs.hpp>
namespace hex::plugin::builtin {
@@ -2551,6 +2553,81 @@ namespace hex::plugin::builtin {
return result;
});
ContentRegistry::MCP::registerTool(romfs::get("mcp/tools/execute_pattern_code.json").string(), [this](const nlohmann::json &data) -> nlohmann::json {
auto provider = ImHexApi::Provider::get();
auto sourceCode = data.at("source_code").get<std::string>();
this->evaluatePattern(sourceCode, provider);
// Wait until evaluation has finished
while (m_runningEvaluators > 0) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
auto lock = std::scoped_lock(ContentRegistry::PatternLanguage::getRuntimeLock());
auto evaluationResult = m_lastEvaluationResult.load();
nlohmann::json result = {
{ "handle", provider->getID() },
{ "result_code", evaluationResult }
};
return mcp::StructuredContent {
.text = result.dump(),
.data = result
};
});
ContentRegistry::MCP::registerTool(romfs::get("mcp/tools/get_pattern_console_content.json").string(), [this](const nlohmann::json &data) -> nlohmann::json {
std::ignore = data;
auto provider = ImHexApi::Provider::get();
// Wait until evaluation has finished
while (m_runningEvaluators > 0) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
auto lock = std::scoped_lock(ContentRegistry::PatternLanguage::getRuntimeLock());
auto consoleOutput = m_console.get(provider);
nlohmann::json result = {
{ "handle", provider->getID() },
{ "content", wolv::util::combineStrings(consoleOutput, "\n") }
};
return mcp::StructuredContent {
.text = result.dump(),
.data = result
};
});
ContentRegistry::MCP::registerTool(romfs::get("mcp/tools/get_patterns.json").string(), [this](const nlohmann::json &data) -> nlohmann::json {
std::ignore = data;
auto provider = ImHexApi::Provider::get();
// Wait until evaluation has finished
while (m_runningEvaluators > 0) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
auto lock = std::scoped_lock(ContentRegistry::PatternLanguage::getRuntimeLock());
pl::gen::fmt::FormatterJson formatter;
auto formattedPatterns = formatter.format(ContentRegistry::PatternLanguage::getRuntime());
nlohmann::json result = {
{ "handle", provider->getID() },
{ "patterns", nlohmann::json::parse(std::string(formattedPatterns.begin(), formattedPatterns.end())) }
};
return mcp::StructuredContent {
.text = result.dump(),
.data = result
};
});
}
void ViewPatternEditor::handleFileChange(prv::Provider *provider) {