feat: Enhance AI agent commands and help interface for improved user experience

This commit is contained in:
scawful
2025-10-04 01:52:51 -04:00
parent 3edc0c5b63
commit ed44ac4e48
3 changed files with 162 additions and 134 deletions

View File

@@ -858,18 +858,23 @@ std::string ResourceLabelManager::CreateOrGetLabel(const std::string& type, cons
// ============================================================================ // ============================================================================
absl::Status YazeProject::InitializeEmbeddedLabels() { absl::Status YazeProject::InitializeEmbeddedLabels() {
// Load all default Zelda3 resource names into resource_labels try {
resource_labels = zelda3::Zelda3Labels::ToResourceLabels(); // Load all default Zelda3 resource names into resource_labels
use_embedded_labels = true; resource_labels = zelda3::Zelda3Labels::ToResourceLabels();
use_embedded_labels = true;
std::cout << "📚 Initialized embedded labels:\n"
<< " - " << resource_labels["room"].size() << " room names\n" std::cout << "📚 Initialized embedded labels:\n"
<< " - " << resource_labels["entrance"].size() << " entrance names\n" << " - " << resource_labels["room"].size() << " room names\n"
<< " - " << resource_labels["sprite"].size() << " sprite names\n" << " - " << resource_labels["entrance"].size() << " entrance names\n"
<< " - " << resource_labels["overlord"].size() << " overlord names\n" << " - " << resource_labels["sprite"].size() << " sprite names\n"
<< " - " << resource_labels["item"].size() << " item names\n"; << " - " << resource_labels["overlord"].size() << " overlord names\n"
<< " - " << resource_labels["item"].size() << " item names\n";
return absl::OkStatus();
return absl::OkStatus();
} catch (const std::exception& e) {
return absl::InternalError(
absl::StrCat("Failed to initialize embedded labels: ", e.what()));
}
} }
std::string YazeProject::GetLabel(const std::string& resource_type, int id, std::string YazeProject::GetLabel(const std::string& resource_type, int id,

View File

@@ -60,18 +60,47 @@ void ModernCLI::SetupCommands() {
commands_["agent"] = { commands_["agent"] = {
.name = "agent", .name = "agent",
.description = "Interact with the AI agent", .description = "🤖 AI-Powered Conversational Agent for ROM Inspection\n"
.usage = "z3ed agent <run|plan|diff|test|test-conversation|gui|list|learn|commit|revert|describe> [options]\n" " Interact naturally with Zelda3 ROM data using embedded labels\n"
" test run: --prompt \"<description>\" [--host <host>] [--port <port>] [--timeout <sec>]\n" " ✨ Features: Natural language queries, automatic label lookup, context-aware responses",
" test status: status --test-id <id> [--follow] [--host <host>] [--port <port>]\n" .usage = "\n"
" test list: list [--category <name>] [--status <state>] [--limit <n>] [--host <host>] [--port <port>]\n" "╔═══════════════════════════════════════════════════════════════════════════╗\n"
" test results: results --test-id <id> [--include-logs] [--format yaml|json] [--host <host>] [--port <port>]\n" " 🤖 AI AGENT COMMANDS ║\n"
" test suite: suite <run|validate|create> [options]\n" "╚═══════════════════════════════════════════════════════════════════════════╝\n"
" test-conversation: [--file <json>] [--verbose] [--rom <path>]\n" "\n"
" gui discover: discover [--window <name>] [--type <widget>] [--path-prefix <path>]\n" "💬 CONVERSATIONAL MODE (Recommended for testing):\n"
" [--include-invisible] [--include-disabled] [--format table|json] [--limit <n>]\n" " z3ed agent test-conversation [--rom=<path>] [--verbose] [--file=<json>]\n"
" describe options: [--resource <name>] [--format json|yaml] [--output <path>]\n" " → Interactive AI testing with all embedded Zelda3 labels\n"
" [--version <value>] [--last-updated <date>]", " → Ask about rooms, sprites, entrances, items naturally\n"
" → Example: 'What sprites are in room 5?' or 'List all dungeons'\n"
"\n"
"💡 SIMPLE CHAT MODE:\n"
" z3ed agent simple-chat \"<your question>\" [--rom=<path>]\n"
" → Quick AI queries with automatic ROM loading\n"
" → Example: z3ed agent simple-chat \"describe entrance 0\"\n"
"\n"
"🎯 ADVANCED CHAT MODE:\n"
" z3ed agent chat \"<prompt>\" [--host=<host>] [--port=<port>]\n"
" → Full conversational AI with Ollama/Gemini\n"
" → Supports multi-turn conversations\n"
"\n"
"📊 TEST MANAGEMENT:\n"
" z3ed agent test run --prompt \"<description>\" [--timeout=<sec>]\n"
" z3ed agent test status --test-id=<id> [--follow]\n"
" z3ed agent test list [--category=<name>] [--status=<state>]\n"
" z3ed agent test results --test-id=<id> [--format=yaml|json]\n"
" z3ed agent test suite <run|validate|create>\n"
"\n"
"🔍 OTHER COMMANDS:\n"
" z3ed agent gui discover [--window=<name>] [--type=<widget>]\n"
" z3ed agent describe [--resource=<name>] [--format=json|yaml]\n"
"\n"
"🏰 EMBEDDED LABELS (Always Available):\n"
" • 296+ room names • 256 sprite names • 133 entrance names\n"
" • 100 item names • 160 overworld maps • 48 music tracks\n"
" • 60 tile types • 26 overlord names • 32 graphics sheets\n"
"\n"
"📚 No separate labels file needed - all names built into z3ed!\n",
.handler = [this](const std::vector<std::string>& args) -> absl::Status { .handler = [this](const std::vector<std::string>& args) -> absl::Status {
return HandleAgentCommand(args); return HandleAgentCommand(args);
} }

View File

@@ -537,142 +537,136 @@ Element ColorBox(const Color &color) {
void HelpComponent(ftxui::ScreenInteractive &screen) { void HelpComponent(ftxui::ScreenInteractive &screen) {
auto help_text = vbox({ auto help_text = vbox({
text("z3ed v0.3.2") | bold | color(Color::Yellow), // Header
text("by scawful") | color(Color::Magenta), text("╔══════════════════════════════════════════════════════════╗") | color(Color::Cyan1) | bold,
text("The Legend of Zelda: A Link to the Past Hacking Tool") | text("║ Z3ED v0.3.2 - AI-Powered CLI ║") | color(Color::Cyan1) | bold,
color(Color::Red), text("║ The Legend of Zelda: A Link to the Past Editor ║") | color(Color::White),
text("Now with Asar 65816 Assembler Integration!") | text("╚══════════════════════════════════════════════════════════╝") | color(Color::Cyan1) | bold,
color(Color::Green), text(""),
hbox({
text("✨ Author: ") | color(Color::Yellow1) | bold,
text("scawful") | color(Color::Magenta),
text("") | color(Color::GrayDark),
text("🤖 AI: ") | color(Color::Green1) | bold,
text("Ollama + Gemini Integration") | color(Color::GreenLight),
}) | center,
text(""),
separator(), separator(),
text("🎯 ASAR COMMANDS") | bold | color(Color::Cyan), // AI Agent Commands
text("") | center,
text("🤖 AI AGENT COMMANDS") | bold | color(Color::Green1) | center,
text(" Conversational AI for ROM inspection and modification") | color(Color::GreenLight) | center,
separator(), separator(),
hbox({ hbox({text(" "), text("💬 Test Chat Mode") | bold | color(Color::Cyan), filler(),
text("Apply Asar Patch"), text("agent test-conversation") | color(Color::White),
filler(), text(" [--rom=<file>] [--verbose]") | color(Color::GrayLight)}),
text("asar"), hbox({text(" "), text("→ Interactive AI testing with embedded labels") | color(Color::GrayLight)}),
filler(), text(""),
text("<patch.asm> [--rom=<file>]"), hbox({text(" "), text("📊 Chat with AI") | bold | color(Color::Cyan), filler(),
}), text("agent chat") | color(Color::White),
hbox({ text(" <prompt> [--host] [--port]") | color(Color::GrayLight)}),
text("Extract Symbols"), hbox({text(" "), text("→ Natural language ROM inspection (rooms, sprites, entrances)") | color(Color::GrayLight)}),
filler(), text(""),
text("extract"), hbox({text(" "), text("🎯 Simple Chat") | bold | color(Color::Cyan), filler(),
filler(), text("agent simple-chat") | color(Color::White),
text("<patch.asm>"), text(" <prompt> [--rom=<file>]") | color(Color::GrayLight)}),
}), hbox({text(" "), text("→ Quick AI queries with automatic ROM loading") | color(Color::GrayLight)}),
hbox({ text(""),
text("Validate Assembly"),
filler(),
text("validate"),
filler(),
text("<patch.asm>"),
}),
separator(), separator(),
text("📦 PATCH COMMANDS") | bold | color(Color::Blue), text("") | center,
text("🎯 ASAR 65816 ASSEMBLER") | bold | color(Color::Yellow1) | center,
text(" Assemble and patch with Asar integration") | color(Color::YellowLight) | center,
separator(), separator(),
hbox({ hbox({text(" "), text("⚡ Apply Patch") | bold | color(Color::Cyan), filler(),
text("Apply BPS Patch"), text("patch apply-asar") | color(Color::White),
filler(), text(" <patch.asm> [--rom=<file>]") | color(Color::GrayLight)}),
text("patch"), hbox({text(" "), text("🔍 Extract Symbols") | bold | color(Color::Cyan), filler(),
filler(), text("patch extract-symbols") | color(Color::White),
text("<patch.bps> [--rom=<file>]"), text(" <patch.asm>") | color(Color::GrayLight)}),
}), hbox({text(" "), text("✓ Validate Assembly") | bold | color(Color::Cyan), filler(),
hbox({ text("patch validate") | color(Color::White),
text("Create BPS Patch"), text(" <patch.asm>") | color(Color::GrayLight)}),
filler(), text(""),
text("create"),
filler(),
text("<src_file> <modified_file>"),
}),
separator(), separator(),
text("🗃️ ROM COMMANDS") | bold | color(Color::Yellow), text("") | center,
text("📦 PATCH MANAGEMENT") | bold | color(Color::Blue) | center,
separator(), separator(),
hbox({ hbox({text(" "), text("Apply BPS Patch") | color(Color::Cyan), filler(),
text("Show ROM Info"), text("patch apply-bps") | color(Color::White),
filler(), text(" <patch.bps> [--rom=<file>]") | color(Color::GrayLight)}),
text("info"), hbox({text(" "), text("Create BPS Patch") | color(Color::Cyan), filler(),
filler(), text("patch create") | color(Color::White),
text("[--rom=<file>]"), text(" <src> <modified>") | color(Color::GrayLight)}),
}), text(""),
hbox({
text("Backup ROM"),
filler(),
text("backup"),
filler(),
text("<rom_file> [backup_name]"),
}),
hbox({
text("Expand ROM"),
filler(),
text("expand"),
filler(),
text("<rom_file> <size>"),
}),
separator(), separator(),
text("🔧 UTILITY COMMANDS") | bold | color(Color::Magenta), text("") | center,
text("🗃️ ROM OPERATIONS") | bold | color(Color::Magenta) | center,
separator(), separator(),
hbox({ hbox({text(" "), text("Show ROM Info") | color(Color::Cyan), filler(),
text("Address Conversion"), text("rom info") | color(Color::White),
filler(), text(" [--rom=<file>]") | color(Color::GrayLight)}),
text("convert"), hbox({text(" "), text("Validate ROM") | color(Color::Cyan), filler(),
filler(), text("rom validate") | color(Color::White),
text("<address> [--to-pc|--to-snes]"), text(" [--rom=<file>]") | color(Color::GrayLight)}),
}), hbox({text(" "), text("Compare ROMs") | color(Color::Cyan), filler(),
hbox({ text("rom diff") | color(Color::White),
text("Transfer Tile16"), text(" <rom_a> <rom_b>") | color(Color::GrayLight)}),
filler(), hbox({text(" "), text("Backup ROM") | color(Color::Cyan), filler(),
text("tile16"), text("rom backup") | color(Color::White),
filler(), text(" <rom_file> [name]") | color(Color::GrayLight)}),
text("<src> <dest> <tiles>"), hbox({text(" "), text("Expand ROM") | color(Color::Cyan), filler(),
}), text("rom expand") | color(Color::White),
text(" <rom_file> <size>") | color(Color::GrayLight)}),
text(""),
separator(), separator(),
text("🌐 GLOBAL FLAGS") | bold | color(Color::White), text("") | center,
text("🏰 EMBEDDED RESOURCE LABELS") | bold | color(Color::Red1) | center,
text(" All Zelda3 names built-in and always available to AI") | color(Color::RedLight) | center,
separator(), separator(),
hbox({ hbox({text(" 📚 296+ Room Names") | color(Color::GreenLight), text("") | color(Color::GrayDark),
text("--tui"), text("256 Sprite Names") | color(Color::GreenLight), text("") | color(Color::GrayDark),
filler(), text("133 Entrance Names") | color(Color::GreenLight)}),
text("Launch Text User Interface"), hbox({text(" 🎨 100 Item Names") | color(Color::GreenLight), text("") | color(Color::GrayDark),
}), text("160 Overworld Maps") | color(Color::GreenLight), text("") | color(Color::GrayDark),
hbox({ text("48 Music Tracks") | color(Color::GreenLight)}),
text("--rom=<file>"), hbox({text(" 🔧 60 Tile Types") | color(Color::GreenLight), text("") | color(Color::GrayDark),
filler(), text("26 Overlord Names") | color(Color::GreenLight), text("") | color(Color::GrayDark),
text("Specify ROM file"), text("32 GFX Sheets") | color(Color::GreenLight)}),
}), text(""),
hbox({
text("--output=<file>"), separator(),
filler(), text("🌐 GLOBAL FLAGS") | bold | color(Color::White) | center,
text("Specify output file"), separator(),
}), hbox({text(" --tui") | color(Color::Cyan), filler(),
hbox({ text("Launch Text User Interface") | color(Color::GrayLight)}),
text("--verbose"), hbox({text(" --rom=<file>") | color(Color::Cyan), filler(),
filler(), text("Specify ROM file") | color(Color::GrayLight)}),
text("Enable verbose output"), hbox({text(" --output=<file>") | color(Color::Cyan), filler(),
}), text("Specify output file") | color(Color::GrayLight)}),
hbox({ hbox({text(" --verbose") | color(Color::Cyan), filler(),
text("--dry-run"), text("Enable verbose output") | color(Color::GrayLight)}),
filler(), hbox({text(" --dry-run") | color(Color::Cyan), filler(),
text("Test without changes"), text("Test without changes") | color(Color::GrayLight)}),
}), text(""),
separator(),
text("Press 'q' to quit, '/' for command palette, 'h' for help") | center | color(Color::GrayLight),
}); });
auto help_text_component = Renderer([&] { return help_text; });
auto back_button = auto back_button =
Button("Back", [&] { SwitchComponents(screen, LayoutID::kMainMenu); }); Button("Back", [&] { SwitchComponents(screen, LayoutID::kMainMenu); });
auto container = Container::Vertical({ auto container = Container::Vertical({
help_text_component,
back_button, back_button,
}); });
auto renderer = Renderer(container, [&] { auto renderer = Renderer(container, [&] {
return vbox({ return vbox({
help_text_component->Render() | center, help_text | vscroll_indicator | frame | flex,
separator(), separator(),
back_button->Render() | center, back_button->Render() | center,
}) | }) |