Implement new agent commands for resource listing and dungeon sprite retrieval
- Added `HandleResourceListCommand` to list resources by type and format (table or JSON). - Introduced `HandleDungeonListSpritesCommand` to retrieve and display sprites from specified dungeon rooms. - Updated command handling in `agent.cc` to support new subcommands. - Enhanced error handling for invalid inputs and missing ROM files. This commit expands the functionality of the z3ed agent, enabling users to interact with game resources and dungeon sprites more effectively.
This commit is contained in:
@@ -59,6 +59,12 @@ absl::Status Agent::Run(const std::vector<std::string>& arg_vec) {
|
|||||||
if (subcommand == "describe") {
|
if (subcommand == "describe") {
|
||||||
return agent::HandleDescribeCommand(subcommand_args);
|
return agent::HandleDescribeCommand(subcommand_args);
|
||||||
}
|
}
|
||||||
|
if (subcommand == "resource-list") {
|
||||||
|
return agent::HandleResourceListCommand(subcommand_args);
|
||||||
|
}
|
||||||
|
if (subcommand == "dungeon-list-sprites") {
|
||||||
|
return agent::HandleDungeonListSpritesCommand(subcommand_args);
|
||||||
|
}
|
||||||
|
|
||||||
return absl::InvalidArgumentError(std::string(agent::kUsage));
|
return absl::InvalidArgumentError(std::string(agent::kUsage));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,10 @@ absl::Status HandleLearnCommand();
|
|||||||
absl::Status HandleListCommand();
|
absl::Status HandleListCommand();
|
||||||
absl::Status HandleCommitCommand(Rom& rom);
|
absl::Status HandleCommitCommand(Rom& rom);
|
||||||
absl::Status HandleRevertCommand(Rom& rom);
|
absl::Status HandleRevertCommand(Rom& rom);
|
||||||
absl::Status HandleDescribeCommand(const std::vector<std::string>& args);
|
absl::Status HandleDescribeCommand(const std::vector<std::string>& arg_vec);
|
||||||
|
absl::Status HandleResourceListCommand(const std::vector<std::string>& arg_vec);
|
||||||
|
absl::Status HandleDungeonListSpritesCommand(
|
||||||
|
const std::vector<std::string>& arg_vec);
|
||||||
|
|
||||||
} // namespace agent
|
} // namespace agent
|
||||||
} // namespace cli
|
} // namespace cli
|
||||||
|
|||||||
@@ -16,21 +16,22 @@
|
|||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#include "absl/strings/str_format.h"
|
#include "absl/strings/str_format.h"
|
||||||
#include "absl/strings/str_replace.h"
|
#include "absl/strings/str_replace.h"
|
||||||
|
#include "app/zelda3/dungeon/room.h"
|
||||||
#include "cli/handlers/agent/common.h"
|
#include "cli/handlers/agent/common.h"
|
||||||
#include "cli/modern_cli.h"
|
#include "cli/modern_cli.h"
|
||||||
#include "cli/service/ai/ai_service.h"
|
#include "cli/service/ai/ai_service.h"
|
||||||
#include "cli/service/ai/ollama_ai_service.h"
|
|
||||||
#include "cli/service/ai/gemini_ai_service.h"
|
#include "cli/service/ai/gemini_ai_service.h"
|
||||||
|
#include "cli/service/ai/ollama_ai_service.h"
|
||||||
#include "cli/service/planning/proposal_registry.h"
|
#include "cli/service/planning/proposal_registry.h"
|
||||||
#include "cli/service/planning/tile16_proposal_generator.h"
|
#include "cli/service/planning/tile16_proposal_generator.h"
|
||||||
#include "cli/service/resources/resource_catalog.h"
|
#include "cli/service/resources/resource_catalog.h"
|
||||||
|
#include "cli/service/resources/resource_context_builder.h"
|
||||||
#include "cli/service/rom/rom_sandbox_manager.h"
|
#include "cli/service/rom/rom_sandbox_manager.h"
|
||||||
#include "cli/z3ed.h"
|
#include "cli/z3ed.h"
|
||||||
#include "util/macro.h"
|
#include "util/macro.h"
|
||||||
|
|
||||||
ABSL_DECLARE_FLAG(std::string, rom);
|
ABSL_DECLARE_FLAG(std::string, rom);
|
||||||
|
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace cli {
|
namespace cli {
|
||||||
namespace agent {
|
namespace agent {
|
||||||
@@ -92,7 +93,9 @@ std::unique_ptr<AIService> CreateAIService() {
|
|||||||
|
|
||||||
// Default: Mock service for testing
|
// Default: Mock service for testing
|
||||||
std::cout << "🤖 Using MockAIService (no LLM configured)" << std::endl;
|
std::cout << "🤖 Using MockAIService (no LLM configured)" << std::endl;
|
||||||
std::cout << " Tip: Set YAZE_AI_PROVIDER=ollama or GEMINI_API_KEY to enable LLM" << std::endl;
|
std::cout
|
||||||
|
<< " Tip: Set YAZE_AI_PROVIDER=ollama or GEMINI_API_KEY to enable LLM"
|
||||||
|
<< std::endl;
|
||||||
return std::make_unique<MockAIService>();
|
return std::make_unique<MockAIService>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,15 +218,14 @@ absl::Status HandleRunCommand(const std::vector<std::string>& arg_vec,
|
|||||||
Rom sandbox_rom;
|
Rom sandbox_rom;
|
||||||
auto load_status = sandbox_rom.LoadFromFile(sandbox.rom_path.string());
|
auto load_status = sandbox_rom.LoadFromFile(sandbox.rom_path.string());
|
||||||
if (!load_status.ok()) {
|
if (!load_status.ok()) {
|
||||||
return absl::InternalError(absl::StrCat(
|
return absl::InternalError(
|
||||||
"Failed to load sandbox ROM: ", load_status.message()));
|
absl::StrCat("Failed to load sandbox ROM: ", load_status.message()));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto apply_status = generator.ApplyProposal(proposal, &sandbox_rom);
|
auto apply_status = generator.ApplyProposal(proposal, &sandbox_rom);
|
||||||
if (!apply_status.ok()) {
|
if (!apply_status.ok()) {
|
||||||
return absl::InternalError(
|
return absl::InternalError(absl::StrCat(
|
||||||
absl::StrCat("Failed to apply proposal to sandbox ROM: ",
|
"Failed to apply proposal to sandbox ROM: ", apply_status.message()));
|
||||||
apply_status.message()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Save the sandbox ROM to persist the changes for diffing
|
// 5. Save the sandbox ROM to persist the changes for diffing
|
||||||
@@ -238,13 +240,15 @@ absl::Status HandleRunCommand(const std::vector<std::string>& arg_vec,
|
|||||||
// A better approach would be to integrate with ProposalRegistry.
|
// A better approach would be to integrate with ProposalRegistry.
|
||||||
auto proposal_path =
|
auto proposal_path =
|
||||||
RomSandboxManager::Instance().RootDirectory() / (proposal.id + ".json");
|
RomSandboxManager::Instance().RootDirectory() / (proposal.id + ".json");
|
||||||
auto save_proposal_status = generator.SaveProposal(proposal, proposal_path.string());
|
auto save_proposal_status =
|
||||||
|
generator.SaveProposal(proposal, proposal_path.string());
|
||||||
if (!save_proposal_status.ok()) {
|
if (!save_proposal_status.ok()) {
|
||||||
return absl::InternalError(absl::StrCat("Failed to save proposal file: ",
|
return absl::InternalError(absl::StrCat("Failed to save proposal file: ",
|
||||||
save_proposal_status.message()));
|
save_proposal_status.message()));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "✅ Agent successfully planned and executed changes in a sandbox."
|
std::cout
|
||||||
|
<< "✅ Agent successfully planned and executed changes in a sandbox."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
std::cout << " Proposal ID: " << proposal.id << std::endl;
|
std::cout << " Proposal ID: " << proposal.id << std::endl;
|
||||||
std::cout << " Sandbox ROM: " << sandbox.rom_path << std::endl;
|
std::cout << " Sandbox ROM: " << sandbox.rom_path << std::endl;
|
||||||
@@ -287,8 +291,7 @@ absl::Status HandlePlanCommand(const std::vector<std::string>& arg_vec) {
|
|||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status HandleDiffCommand(Rom& rom,
|
absl::Status HandleDiffCommand(Rom& rom, const std::vector<std::string>& args) {
|
||||||
const std::vector<std::string>& args) {
|
|
||||||
std::optional<std::string> proposal_id;
|
std::optional<std::string> proposal_id;
|
||||||
for (size_t i = 0; i < args.size(); ++i) {
|
for (size_t i = 0; i < args.size(); ++i) {
|
||||||
const std::string& token = args[i];
|
const std::string& token = args[i];
|
||||||
@@ -329,10 +332,8 @@ absl::Status HandleDiffCommand(Rom& rom,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
std::cout << "\n";
|
std::cout << "\n";
|
||||||
std::cout << "Created: " << absl::FormatTime(proposal.created_at)
|
std::cout << "Created: " << absl::FormatTime(proposal.created_at) << "\n";
|
||||||
<< "\n";
|
std::cout << "Commands Executed: " << proposal.commands_executed << "\n";
|
||||||
std::cout << "Commands Executed: " << proposal.commands_executed
|
|
||||||
<< "\n";
|
|
||||||
std::cout << "Bytes Changed: " << proposal.bytes_changed << "\n\n";
|
std::cout << "Bytes Changed: " << proposal.bytes_changed << "\n\n";
|
||||||
|
|
||||||
if (std::filesystem::exists(proposal.diff_path)) {
|
if (std::filesystem::exists(proposal.diff_path)) {
|
||||||
@@ -384,7 +385,8 @@ absl::Status HandleDiffCommand(Rom& rom,
|
|||||||
auto sandbox_or = RomSandboxManager::Instance().ActiveSandbox();
|
auto sandbox_or = RomSandboxManager::Instance().ActiveSandbox();
|
||||||
if (!sandbox_or.ok()) {
|
if (!sandbox_or.ok()) {
|
||||||
return absl::NotFoundError(
|
return absl::NotFoundError(
|
||||||
"No pending proposals found and no active sandbox. Run 'z3ed agent run' first.");
|
"No pending proposals found and no active sandbox. Run 'z3ed agent "
|
||||||
|
"run' first.");
|
||||||
}
|
}
|
||||||
RomDiff diff_handler;
|
RomDiff diff_handler;
|
||||||
auto status =
|
auto status =
|
||||||
@@ -431,8 +433,7 @@ absl::Status HandleListCommand() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
std::cout << "\n";
|
std::cout << "\n";
|
||||||
std::cout << " Created: " << absl::FormatTime(proposal.created_at)
|
std::cout << " Created: " << absl::FormatTime(proposal.created_at) << "\n";
|
||||||
<< "\n";
|
|
||||||
std::cout << " Prompt: " << proposal.prompt << "\n";
|
std::cout << " Prompt: " << proposal.prompt << "\n";
|
||||||
std::cout << " Commands: " << proposal.commands_executed << "\n";
|
std::cout << " Commands: " << proposal.commands_executed << "\n";
|
||||||
std::cout << " Bytes Changed: " << proposal.bytes_changed << "\n";
|
std::cout << " Bytes Changed: " << proposal.bytes_changed << "\n";
|
||||||
@@ -492,17 +493,17 @@ absl::Status HandleDescribeCommand(const std::vector<std::string>& arg_vec) {
|
|||||||
payload = catalog.SerializeResources(catalog.AllResources());
|
payload = catalog.SerializeResources(catalog.AllResources());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::string last_updated = options.last_updated.has_value()
|
std::string last_updated =
|
||||||
|
options.last_updated.has_value()
|
||||||
? *options.last_updated
|
? *options.last_updated
|
||||||
: absl::FormatTime("%Y-%m-%d", absl::Now(),
|
: absl::FormatTime("%Y-%m-%d", absl::Now(), absl::LocalTimeZone());
|
||||||
absl::LocalTimeZone());
|
|
||||||
if (resource_schema.has_value()) {
|
if (resource_schema.has_value()) {
|
||||||
std::vector<ResourceSchema> schemas{*resource_schema};
|
std::vector<ResourceSchema> schemas{*resource_schema};
|
||||||
payload = catalog.SerializeResourcesAsYaml(
|
payload = catalog.SerializeResourcesAsYaml(schemas, options.version,
|
||||||
schemas, options.version, last_updated);
|
last_updated);
|
||||||
} else {
|
} else {
|
||||||
payload = catalog.SerializeResourcesAsYaml(
|
payload = catalog.SerializeResourcesAsYaml(catalog.AllResources(),
|
||||||
catalog.AllResources(), options.version, last_updated);
|
options.version, last_updated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -515,8 +516,8 @@ absl::Status HandleDescribeCommand(const std::vector<std::string>& arg_vec) {
|
|||||||
out << payload;
|
out << payload;
|
||||||
out.close();
|
out.close();
|
||||||
if (!out) {
|
if (!out) {
|
||||||
return absl::InternalError(absl::StrFormat(
|
return absl::InternalError(absl::StrFormat("Failed to write schema to %s",
|
||||||
"Failed to write schema to %s", *options.output_path));
|
*options.output_path));
|
||||||
}
|
}
|
||||||
std::cout << absl::StrFormat("Wrote %s schema to %s", options.format,
|
std::cout << absl::StrFormat("Wrote %s schema to %s", options.format,
|
||||||
*options.output_path)
|
*options.output_path)
|
||||||
@@ -528,6 +529,160 @@ absl::Status HandleDescribeCommand(const std::vector<std::string>& arg_vec) {
|
|||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
absl::Status HandleResourceListCommand(
|
||||||
|
const std::vector<std::string>& arg_vec) {
|
||||||
|
std::string type;
|
||||||
|
std::string format = "table";
|
||||||
|
|
||||||
|
for (size_t i = 0; i < arg_vec.size(); ++i) {
|
||||||
|
const std::string& token = arg_vec[i];
|
||||||
|
if (token == "--type") {
|
||||||
|
if (i + 1 < arg_vec.size()) {
|
||||||
|
type = arg_vec[++i];
|
||||||
|
} else {
|
||||||
|
return absl::InvalidArgumentError("--type requires a value.");
|
||||||
|
}
|
||||||
|
} else if (absl::StartsWith(token, "--type=")) {
|
||||||
|
type = token.substr(7);
|
||||||
|
} else if (token == "--format") {
|
||||||
|
if (i + 1 < arg_vec.size()) {
|
||||||
|
format = arg_vec[++i];
|
||||||
|
} else {
|
||||||
|
return absl::InvalidArgumentError("--format requires a value.");
|
||||||
|
}
|
||||||
|
} else if (absl::StartsWith(token, "--format=")) {
|
||||||
|
format = token.substr(9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.empty()) {
|
||||||
|
return absl::InvalidArgumentError(
|
||||||
|
"Usage: agent resource-list --type <type> [--format <table|json>]");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Load the ROM
|
||||||
|
std::string rom_path = absl::GetFlag(FLAGS_rom);
|
||||||
|
if (rom_path.empty()) {
|
||||||
|
return absl::FailedPreconditionError(
|
||||||
|
"No ROM loaded. Use --rom=<path> to specify ROM file.");
|
||||||
|
}
|
||||||
|
Rom rom;
|
||||||
|
auto status = rom.LoadFromFile(rom_path);
|
||||||
|
if (!status.ok()) {
|
||||||
|
return absl::FailedPreconditionError(absl::StrFormat(
|
||||||
|
"Failed to load ROM from '%s': %s", rom_path, status.message()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Get labels using ResourceContextBuilder
|
||||||
|
ResourceContextBuilder context_builder(&rom);
|
||||||
|
auto labels_or = context_builder.GetLabels(type);
|
||||||
|
if (!labels_or.ok()) {
|
||||||
|
return labels_or.status();
|
||||||
|
}
|
||||||
|
auto labels = labels_or.value();
|
||||||
|
|
||||||
|
// 3. Format and print output
|
||||||
|
if (format == "json") {
|
||||||
|
std::cout << "{\n";
|
||||||
|
bool first = true;
|
||||||
|
for (const auto& [key, value] : labels) {
|
||||||
|
if (!first) {
|
||||||
|
std::cout << ",\n";
|
||||||
|
}
|
||||||
|
std::cout << " \"" << key << "\": \"" << value << "\"";
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
std::cout << "\n}\n";
|
||||||
|
} else { // Table format
|
||||||
|
std::cout << "=== " << absl::AsciiStrToUpper(type) << " Labels ===\n";
|
||||||
|
for (const auto& [key, value] : labels) {
|
||||||
|
std::cout << absl::StrFormat(" %-10s : %s\n", key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::Status HandleDungeonListSpritesCommand(
|
||||||
|
const std::vector<std::string>& arg_vec) {
|
||||||
|
std::string room_id_str;
|
||||||
|
std::string format = "table";
|
||||||
|
|
||||||
|
for (size_t i = 0; i < arg_vec.size(); ++i) {
|
||||||
|
const std::string& token = arg_vec[i];
|
||||||
|
if (token == "--room") {
|
||||||
|
if (i + 1 < arg_vec.size()) {
|
||||||
|
room_id_str = arg_vec[++i];
|
||||||
|
} else {
|
||||||
|
return absl::InvalidArgumentError("--room requires a value.");
|
||||||
|
}
|
||||||
|
} else if (absl::StartsWith(token, "--room=")) {
|
||||||
|
room_id_str = token.substr(7);
|
||||||
|
} else if (token == "--format") {
|
||||||
|
if (i + 1 < arg_vec.size()) {
|
||||||
|
format = arg_vec[++i];
|
||||||
|
} else {
|
||||||
|
return absl::InvalidArgumentError("--format requires a value.");
|
||||||
|
}
|
||||||
|
} else if (absl::StartsWith(token, "--format=")) {
|
||||||
|
format = token.substr(9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (room_id_str.empty()) {
|
||||||
|
return absl::InvalidArgumentError(
|
||||||
|
"Usage: agent dungeon-list-sprites --room <id> [--format "
|
||||||
|
"<table|json>]");
|
||||||
|
}
|
||||||
|
|
||||||
|
int room_id;
|
||||||
|
if (!absl::SimpleHexAtoi(room_id_str, &room_id)) {
|
||||||
|
return absl::InvalidArgumentError("Invalid room ID format. Must be hex.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Load the ROM
|
||||||
|
std::string rom_path = absl::GetFlag(FLAGS_rom);
|
||||||
|
if (rom_path.empty()) {
|
||||||
|
return absl::FailedPreconditionError(
|
||||||
|
"No ROM loaded. Use --rom=<path> to specify ROM file.");
|
||||||
|
}
|
||||||
|
Rom rom;
|
||||||
|
auto status = rom.LoadFromFile(rom_path);
|
||||||
|
if (!status.ok()) {
|
||||||
|
return absl::FailedPreconditionError(absl::StrFormat(
|
||||||
|
"Failed to load ROM from '%s': %s", rom_path, status.message()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Load dungeon room and get sprites
|
||||||
|
auto room = zelda3::LoadRoomFromRom(&rom, room_id);
|
||||||
|
const auto& sprites = room.GetSprites();
|
||||||
|
|
||||||
|
// 3. Format and print output
|
||||||
|
if (format == "json") {
|
||||||
|
std::cout << "[\n";
|
||||||
|
for (size_t i = 0; i < sprites.size(); ++i) {
|
||||||
|
const auto& sprite = sprites[i];
|
||||||
|
std::cout << " {\n";
|
||||||
|
std::cout << " \"id\": " << sprite.id() << ",\n";
|
||||||
|
std::cout << " \"x\": " << sprite.x() << ",\n";
|
||||||
|
std::cout << " \"y\": " << sprite.y() << "\n";
|
||||||
|
std::cout << " }" << (i == sprites.size() - 1 ? "" : ",");
|
||||||
|
std::cout << "\n";
|
||||||
|
}
|
||||||
|
std::cout << "]\n";
|
||||||
|
} else { // Table format
|
||||||
|
std::cout << "=== Sprites in Room " << room_id_str << " ===\n";
|
||||||
|
std::cout << absl::StrFormat("%-10s %-5s %-5s\n", "ID (Hex)", "X", "Y");
|
||||||
|
std::cout << std::string(22, '-') << "\n";
|
||||||
|
for (const auto& sprite : sprites) {
|
||||||
|
std::cout << absl::StrFormat("0x%-8X %-5d %-5d\n", sprite.id(),
|
||||||
|
sprite.x(), sprite.y());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
absl::Status HandleAcceptCommand(const std::vector<std::string>& arg_vec,
|
absl::Status HandleAcceptCommand(const std::vector<std::string>& arg_vec,
|
||||||
Rom& rom) {
|
Rom& rom) {
|
||||||
if (arg_vec.empty() || arg_vec[0] != "--proposal-id") {
|
if (arg_vec.empty() || arg_vec[0] != "--proposal-id") {
|
||||||
@@ -542,8 +697,8 @@ absl::Status HandleAcceptCommand(const std::vector<std::string>& arg_vec,
|
|||||||
RomSandboxManager::Instance().RootDirectory() / (proposal_id + ".json");
|
RomSandboxManager::Instance().RootDirectory() / (proposal_id + ".json");
|
||||||
auto proposal_or = generator.LoadProposal(proposal_path.string());
|
auto proposal_or = generator.LoadProposal(proposal_path.string());
|
||||||
if (!proposal_or.ok()) {
|
if (!proposal_or.ok()) {
|
||||||
return absl::InternalError(absl::StrCat("Failed to load proposal file '",
|
return absl::InternalError(
|
||||||
proposal_path.string(),
|
absl::StrCat("Failed to load proposal file '", proposal_path.string(),
|
||||||
"': ", proposal_or.status().message()));
|
"': ", proposal_or.status().message()));
|
||||||
}
|
}
|
||||||
auto proposal = proposal_or.value();
|
auto proposal = proposal_or.value();
|
||||||
@@ -551,23 +706,22 @@ absl::Status HandleAcceptCommand(const std::vector<std::string>& arg_vec,
|
|||||||
// 2. Ensure the main ROM is loaded.
|
// 2. Ensure the main ROM is loaded.
|
||||||
if (!rom.is_loaded()) {
|
if (!rom.is_loaded()) {
|
||||||
return absl::FailedPreconditionError(
|
return absl::FailedPreconditionError(
|
||||||
"No ROM loaded. Use --rom=<path> to specify the ROM to apply changes to.");
|
"No ROM loaded. Use --rom=<path> to specify the ROM to apply changes "
|
||||||
|
"to.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Apply the proposal to the main ROM.
|
// 3. Apply the proposal to the main ROM.
|
||||||
auto apply_status = generator.ApplyProposal(proposal, &rom);
|
auto apply_status = generator.ApplyProposal(proposal, &rom);
|
||||||
if (!apply_status.ok()) {
|
if (!apply_status.ok()) {
|
||||||
return absl::InternalError(
|
return absl::InternalError(absl::StrCat(
|
||||||
absl::StrCat("Failed to apply proposal to main ROM: ",
|
"Failed to apply proposal to main ROM: ", apply_status.message()));
|
||||||
apply_status.message()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Save the changes to the main ROM file.
|
// 4. Save the changes to the main ROM file.
|
||||||
auto save_status = rom.SaveToFile({.save_new = false});
|
auto save_status = rom.SaveToFile({.save_new = false});
|
||||||
if (!save_status.ok()) {
|
if (!save_status.ok()) {
|
||||||
return absl::InternalError(
|
return absl::InternalError(absl::StrCat(
|
||||||
absl::StrCat("Failed to save changes to main ROM: ",
|
"Failed to save changes to main ROM: ", save_status.message()));
|
||||||
save_status.message()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "✅ Proposal '" << proposal_id << "' accepted and applied to '"
|
std::cout << "✅ Proposal '" << proposal_id << "' accepted and applied to '"
|
||||||
|
|||||||
Reference in New Issue
Block a user