feat: Enhance AI agent commands and help interface for improved user experience
This commit is contained in:
@@ -858,18 +858,23 @@ std::string ResourceLabelManager::CreateOrGetLabel(const std::string& type, cons
|
||||
// ============================================================================
|
||||
|
||||
absl::Status YazeProject::InitializeEmbeddedLabels() {
|
||||
// Load all default Zelda3 resource names into resource_labels
|
||||
resource_labels = zelda3::Zelda3Labels::ToResourceLabels();
|
||||
use_embedded_labels = true;
|
||||
|
||||
std::cout << "📚 Initialized embedded labels:\n"
|
||||
<< " - " << resource_labels["room"].size() << " room names\n"
|
||||
<< " - " << resource_labels["entrance"].size() << " entrance names\n"
|
||||
<< " - " << resource_labels["sprite"].size() << " sprite names\n"
|
||||
<< " - " << resource_labels["overlord"].size() << " overlord names\n"
|
||||
<< " - " << resource_labels["item"].size() << " item names\n";
|
||||
|
||||
return absl::OkStatus();
|
||||
try {
|
||||
// Load all default Zelda3 resource names into resource_labels
|
||||
resource_labels = zelda3::Zelda3Labels::ToResourceLabels();
|
||||
use_embedded_labels = true;
|
||||
|
||||
std::cout << "📚 Initialized embedded labels:\n"
|
||||
<< " - " << resource_labels["room"].size() << " room names\n"
|
||||
<< " - " << resource_labels["entrance"].size() << " entrance names\n"
|
||||
<< " - " << resource_labels["sprite"].size() << " sprite names\n"
|
||||
<< " - " << resource_labels["overlord"].size() << " overlord names\n"
|
||||
<< " - " << resource_labels["item"].size() << " item names\n";
|
||||
|
||||
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,
|
||||
|
||||
@@ -60,18 +60,47 @@ void ModernCLI::SetupCommands() {
|
||||
|
||||
commands_["agent"] = {
|
||||
.name = "agent",
|
||||
.description = "Interact with the AI agent",
|
||||
.usage = "z3ed agent <run|plan|diff|test|test-conversation|gui|list|learn|commit|revert|describe> [options]\n"
|
||||
" test run: --prompt \"<description>\" [--host <host>] [--port <port>] [--timeout <sec>]\n"
|
||||
" test status: status --test-id <id> [--follow] [--host <host>] [--port <port>]\n"
|
||||
" test list: list [--category <name>] [--status <state>] [--limit <n>] [--host <host>] [--port <port>]\n"
|
||||
" test results: results --test-id <id> [--include-logs] [--format yaml|json] [--host <host>] [--port <port>]\n"
|
||||
" test suite: suite <run|validate|create> [options]\n"
|
||||
" test-conversation: [--file <json>] [--verbose] [--rom <path>]\n"
|
||||
" gui discover: discover [--window <name>] [--type <widget>] [--path-prefix <path>]\n"
|
||||
" [--include-invisible] [--include-disabled] [--format table|json] [--limit <n>]\n"
|
||||
" describe options: [--resource <name>] [--format json|yaml] [--output <path>]\n"
|
||||
" [--version <value>] [--last-updated <date>]",
|
||||
.description = "🤖 AI-Powered Conversational Agent for ROM Inspection\n"
|
||||
" Interact naturally with Zelda3 ROM data using embedded labels\n"
|
||||
" ✨ Features: Natural language queries, automatic label lookup, context-aware responses",
|
||||
.usage = "\n"
|
||||
"╔═══════════════════════════════════════════════════════════════════════════╗\n"
|
||||
"║ 🤖 AI AGENT COMMANDS ║\n"
|
||||
"╚═══════════════════════════════════════════════════════════════════════════╝\n"
|
||||
"\n"
|
||||
"💬 CONVERSATIONAL MODE (Recommended for testing):\n"
|
||||
" z3ed agent test-conversation [--rom=<path>] [--verbose] [--file=<json>]\n"
|
||||
" → Interactive AI testing with all embedded Zelda3 labels\n"
|
||||
" → 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 {
|
||||
return HandleAgentCommand(args);
|
||||
}
|
||||
|
||||
214
src/cli/tui.cc
214
src/cli/tui.cc
@@ -537,142 +537,136 @@ Element ColorBox(const Color &color) {
|
||||
|
||||
void HelpComponent(ftxui::ScreenInteractive &screen) {
|
||||
auto help_text = vbox({
|
||||
text("z3ed v0.3.2") | bold | color(Color::Yellow),
|
||||
text("by scawful") | color(Color::Magenta),
|
||||
text("The Legend of Zelda: A Link to the Past Hacking Tool") |
|
||||
color(Color::Red),
|
||||
text("Now with Asar 65816 Assembler Integration!") |
|
||||
color(Color::Green),
|
||||
// Header
|
||||
text("╔══════════════════════════════════════════════════════════╗") | color(Color::Cyan1) | bold,
|
||||
text("║ Z3ED v0.3.2 - AI-Powered CLI ║") | color(Color::Cyan1) | bold,
|
||||
text("║ The Legend of Zelda: A Link to the Past Editor ║") | color(Color::White),
|
||||
text("╚══════════════════════════════════════════════════════════╝") | color(Color::Cyan1) | bold,
|
||||
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(),
|
||||
|
||||
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(),
|
||||
hbox({
|
||||
text("Apply Asar Patch"),
|
||||
filler(),
|
||||
text("asar"),
|
||||
filler(),
|
||||
text("<patch.asm> [--rom=<file>]"),
|
||||
}),
|
||||
hbox({
|
||||
text("Extract Symbols"),
|
||||
filler(),
|
||||
text("extract"),
|
||||
filler(),
|
||||
text("<patch.asm>"),
|
||||
}),
|
||||
hbox({
|
||||
text("Validate Assembly"),
|
||||
filler(),
|
||||
text("validate"),
|
||||
filler(),
|
||||
text("<patch.asm>"),
|
||||
}),
|
||||
hbox({text(" "), text("💬 Test Chat Mode") | bold | color(Color::Cyan), filler(),
|
||||
text("agent test-conversation") | color(Color::White),
|
||||
text(" [--rom=<file>] [--verbose]") | color(Color::GrayLight)}),
|
||||
hbox({text(" "), text("→ Interactive AI testing with embedded labels") | color(Color::GrayLight)}),
|
||||
text(""),
|
||||
hbox({text(" "), text("📊 Chat with AI") | bold | color(Color::Cyan), filler(),
|
||||
text("agent chat") | color(Color::White),
|
||||
text(" <prompt> [--host] [--port]") | color(Color::GrayLight)}),
|
||||
hbox({text(" "), text("→ Natural language ROM inspection (rooms, sprites, entrances)") | color(Color::GrayLight)}),
|
||||
text(""),
|
||||
hbox({text(" "), text("🎯 Simple Chat") | bold | color(Color::Cyan), filler(),
|
||||
text("agent simple-chat") | color(Color::White),
|
||||
text(" <prompt> [--rom=<file>]") | color(Color::GrayLight)}),
|
||||
hbox({text(" "), text("→ Quick AI queries with automatic ROM loading") | color(Color::GrayLight)}),
|
||||
text(""),
|
||||
|
||||
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(),
|
||||
hbox({
|
||||
text("Apply BPS Patch"),
|
||||
filler(),
|
||||
text("patch"),
|
||||
filler(),
|
||||
text("<patch.bps> [--rom=<file>]"),
|
||||
}),
|
||||
hbox({
|
||||
text("Create BPS Patch"),
|
||||
filler(),
|
||||
text("create"),
|
||||
filler(),
|
||||
text("<src_file> <modified_file>"),
|
||||
}),
|
||||
hbox({text(" "), text("⚡ Apply Patch") | bold | color(Color::Cyan), filler(),
|
||||
text("patch apply-asar") | color(Color::White),
|
||||
text(" <patch.asm> [--rom=<file>]") | color(Color::GrayLight)}),
|
||||
hbox({text(" "), text("🔍 Extract Symbols") | bold | color(Color::Cyan), filler(),
|
||||
text("patch extract-symbols") | color(Color::White),
|
||||
text(" <patch.asm>") | color(Color::GrayLight)}),
|
||||
hbox({text(" "), text("✓ Validate Assembly") | bold | color(Color::Cyan), filler(),
|
||||
text("patch validate") | color(Color::White),
|
||||
text(" <patch.asm>") | color(Color::GrayLight)}),
|
||||
text(""),
|
||||
|
||||
separator(),
|
||||
text("🗃️ ROM COMMANDS") | bold | color(Color::Yellow),
|
||||
text("") | center,
|
||||
text("📦 PATCH MANAGEMENT") | bold | color(Color::Blue) | center,
|
||||
separator(),
|
||||
hbox({
|
||||
text("Show ROM Info"),
|
||||
filler(),
|
||||
text("info"),
|
||||
filler(),
|
||||
text("[--rom=<file>]"),
|
||||
}),
|
||||
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>"),
|
||||
}),
|
||||
hbox({text(" "), text("Apply BPS Patch") | color(Color::Cyan), filler(),
|
||||
text("patch apply-bps") | color(Color::White),
|
||||
text(" <patch.bps> [--rom=<file>]") | color(Color::GrayLight)}),
|
||||
hbox({text(" "), text("Create BPS Patch") | color(Color::Cyan), filler(),
|
||||
text("patch create") | color(Color::White),
|
||||
text(" <src> <modified>") | color(Color::GrayLight)}),
|
||||
text(""),
|
||||
|
||||
separator(),
|
||||
text("🔧 UTILITY COMMANDS") | bold | color(Color::Magenta),
|
||||
text("") | center,
|
||||
text("🗃️ ROM OPERATIONS") | bold | color(Color::Magenta) | center,
|
||||
separator(),
|
||||
hbox({
|
||||
text("Address Conversion"),
|
||||
filler(),
|
||||
text("convert"),
|
||||
filler(),
|
||||
text("<address> [--to-pc|--to-snes]"),
|
||||
}),
|
||||
hbox({
|
||||
text("Transfer Tile16"),
|
||||
filler(),
|
||||
text("tile16"),
|
||||
filler(),
|
||||
text("<src> <dest> <tiles>"),
|
||||
}),
|
||||
hbox({text(" "), text("Show ROM Info") | color(Color::Cyan), filler(),
|
||||
text("rom info") | color(Color::White),
|
||||
text(" [--rom=<file>]") | color(Color::GrayLight)}),
|
||||
hbox({text(" "), text("Validate ROM") | color(Color::Cyan), filler(),
|
||||
text("rom validate") | color(Color::White),
|
||||
text(" [--rom=<file>]") | color(Color::GrayLight)}),
|
||||
hbox({text(" "), text("Compare ROMs") | color(Color::Cyan), filler(),
|
||||
text("rom diff") | color(Color::White),
|
||||
text(" <rom_a> <rom_b>") | color(Color::GrayLight)}),
|
||||
hbox({text(" "), text("Backup ROM") | color(Color::Cyan), filler(),
|
||||
text("rom backup") | color(Color::White),
|
||||
text(" <rom_file> [name]") | color(Color::GrayLight)}),
|
||||
hbox({text(" "), text("Expand ROM") | color(Color::Cyan), filler(),
|
||||
text("rom expand") | color(Color::White),
|
||||
text(" <rom_file> <size>") | color(Color::GrayLight)}),
|
||||
text(""),
|
||||
|
||||
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(),
|
||||
hbox({
|
||||
text("--tui"),
|
||||
filler(),
|
||||
text("Launch Text User Interface"),
|
||||
}),
|
||||
hbox({
|
||||
text("--rom=<file>"),
|
||||
filler(),
|
||||
text("Specify ROM file"),
|
||||
}),
|
||||
hbox({
|
||||
text("--output=<file>"),
|
||||
filler(),
|
||||
text("Specify output file"),
|
||||
}),
|
||||
hbox({
|
||||
text("--verbose"),
|
||||
filler(),
|
||||
text("Enable verbose output"),
|
||||
}),
|
||||
hbox({
|
||||
text("--dry-run"),
|
||||
filler(),
|
||||
text("Test without changes"),
|
||||
}),
|
||||
hbox({text(" 📚 296+ Room Names") | color(Color::GreenLight), text(" │ ") | color(Color::GrayDark),
|
||||
text("256 Sprite Names") | color(Color::GreenLight), text(" │ ") | color(Color::GrayDark),
|
||||
text("133 Entrance Names") | color(Color::GreenLight)}),
|
||||
hbox({text(" 🎨 100 Item Names") | color(Color::GreenLight), text(" │ ") | color(Color::GrayDark),
|
||||
text("160 Overworld Maps") | color(Color::GreenLight), text(" │ ") | color(Color::GrayDark),
|
||||
text("48 Music Tracks") | color(Color::GreenLight)}),
|
||||
hbox({text(" 🔧 60 Tile Types") | color(Color::GreenLight), text(" │ ") | color(Color::GrayDark),
|
||||
text("26 Overlord Names") | color(Color::GreenLight), text(" │ ") | color(Color::GrayDark),
|
||||
text("32 GFX Sheets") | color(Color::GreenLight)}),
|
||||
text(""),
|
||||
|
||||
separator(),
|
||||
text("🌐 GLOBAL FLAGS") | bold | color(Color::White) | center,
|
||||
separator(),
|
||||
hbox({text(" --tui") | color(Color::Cyan), filler(),
|
||||
text("Launch Text User Interface") | color(Color::GrayLight)}),
|
||||
hbox({text(" --rom=<file>") | color(Color::Cyan), filler(),
|
||||
text("Specify ROM file") | color(Color::GrayLight)}),
|
||||
hbox({text(" --output=<file>") | color(Color::Cyan), filler(),
|
||||
text("Specify output file") | color(Color::GrayLight)}),
|
||||
hbox({text(" --verbose") | color(Color::Cyan), filler(),
|
||||
text("Enable verbose output") | color(Color::GrayLight)}),
|
||||
hbox({text(" --dry-run") | color(Color::Cyan), filler(),
|
||||
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 =
|
||||
Button("Back", [&] { SwitchComponents(screen, LayoutID::kMainMenu); });
|
||||
|
||||
auto container = Container::Vertical({
|
||||
help_text_component,
|
||||
back_button,
|
||||
});
|
||||
|
||||
auto renderer = Renderer(container, [&] {
|
||||
return vbox({
|
||||
help_text_component->Render() | center,
|
||||
help_text | vscroll_indicator | frame | flex,
|
||||
separator(),
|
||||
back_button->Render() | center,
|
||||
}) |
|
||||
|
||||
Reference in New Issue
Block a user