yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
advanced_routing.cc
Go to the documentation of this file.
2
3#include <algorithm>
4#include <map>
5#include <sstream>
6
7#include "absl/strings/str_format.h"
8#include "absl/strings/str_join.h"
9
10namespace yaze {
11namespace cli {
12namespace agent {
13
15 const std::vector<uint8_t>& data, uint32_t address,
16 const RouteContext& ctx) {
17 RoutedResponse response;
18
19 // Infer data type
20 std::string data_type = InferDataType(data);
21 auto patterns = ExtractPatterns(data);
22
23 // Summary for user
24 response.summary = absl::StrFormat("Address 0x%06X contains %s (%zu bytes)",
25 address, data_type, data.size());
26
27 // Detailed data for agent with structure hints
28 std::ostringstream detailed;
29 detailed << absl::StrFormat("Raw hex at 0x%06X:\n", address);
30 for (size_t i = 0; i < data.size(); i += 16) {
31 detailed << absl::StrFormat("%06X: ", address + i);
32 for (size_t j = i; j < std::min(i + 16, data.size()); ++j) {
33 detailed << absl::StrFormat("%02X ", data[j]);
34 }
35 detailed << " | ";
36 for (size_t j = i; j < std::min(i + 16, data.size()); ++j) {
37 char c = data[j];
38 detailed << (isprint(c) ? c : '.');
39 }
40 detailed << "\n";
41 }
42
43 if (!patterns.empty()) {
44 detailed << "\nDetected patterns:\n";
45 for (const auto& pattern : patterns) {
46 detailed << "- " << pattern << "\n";
47 }
48 }
49
50 response.detailed_data = detailed.str();
51
52 // Next steps based on data type
53 if (data_type.find("sprite") != std::string::npos) {
54 response.next_steps =
55 "Use resource-list --type=sprite to identify sprite IDs";
56 } else if (data_type.find("tile") != std::string::npos) {
57 response.next_steps =
58 "Use overworld-find-tile to see where this tile appears";
59 } else if (data_type.find("palette") != std::string::npos) {
60 response.next_steps =
61 "Use palette-get-colors for a generic preview, or "
62 "dungeon-get-palette with a room ID to resolve shared dungeon scope";
63 } else {
64 response.next_steps = "Use hex-search to find similar patterns in ROM";
65 }
66
67 return response;
68}
69
71 const std::string& edit_intent, const RouteContext& ctx) {
72 RoutedResponse response;
73
74 // Parse intent and generate action sequence
75 response.summary = "Preparing map edit operation";
76 response.needs_approval = true;
77
78 // Generate GUI automation steps
79 response.gui_actions = {
80 "Click(\"Overworld Editor\")",
81 "Wait(500)",
82 "Click(canvas, x, y)",
83 "SelectTile(tile_id)",
84 "Click(target_x, target_y)",
85 "Wait(100)",
86 "Screenshot(\"after_edit.png\")",
87 };
88
89 response.detailed_data = GenerateGUIScript(response.gui_actions);
90 response.next_steps = "Review proposed changes, then approve or modify";
91
92 return response;
93}
94
96 const std::vector<uint16_t>& colors, const RouteContext& ctx) {
97 RoutedResponse response;
98
99 // Analyze color relationships
100 int unique_colors = 0;
101 std::map<uint16_t, int> color_counts;
102 for (uint16_t c : colors) {
103 color_counts[c]++;
104 }
105 unique_colors = color_counts.size();
106
107 response.summary = absl::StrFormat("Palette has %zu colors (%d unique)",
108 colors.size(), unique_colors);
109
110 // Detailed breakdown
111 std::ostringstream detailed;
112 detailed << "Color breakdown:\n";
113 for (size_t i = 0; i < colors.size(); ++i) {
114 uint16_t snes = colors[i];
115 uint8_t r = (snes & 0x1F) << 3;
116 uint8_t g = ((snes >> 5) & 0x1F) << 3;
117 uint8_t b = ((snes >> 10) & 0x1F) << 3;
118 detailed << absl::StrFormat(" [%zu] $%04X = #%02X%02X%02X\n", i, snes, r,
119 g, b);
120 }
121
122 if (color_counts.size() < colors.size()) {
123 detailed << "\nDuplicates found - optimization possible\n";
124 }
125
126 response.detailed_data = detailed.str();
127 response.next_steps =
128 "Legacy palette-set-color is preview-only. For a dungeon palette, use "
129 "dungeon-get-palette, then dry-run dungeon-set-palette-color with exact "
130 "CAS values and a Hack Manifest before requesting --write";
131
132 return response;
133}
134
136 const std::vector<std::string>& tool_results, const RouteContext& ctx) {
137 RoutedResponse response;
138
139 // Combine results intelligently
140 response.summary =
141 absl::StrFormat("Analyzed %zu data sources", tool_results.size());
142 response.detailed_data = absl::StrJoin(tool_results, "\n---\n");
143
144 // Generate insights
145 response.next_steps = "Analysis complete. " + ctx.user_intent;
146
147 return response;
148}
149
151 const std::vector<std::string>& actions) {
152 std::ostringstream script;
153 script << "# Generated GUI Automation Script\n";
154 script << "test: \"Automated Edit\"\n";
155 script << "steps:\n";
156 for (const auto& action : actions) {
157 script << " - " << action << "\n";
158 }
159 return script.str();
160}
161
162std::string AdvancedRouter::InferDataType(const std::vector<uint8_t>& data) {
163 if (data.size() == 8)
164 return "tile16 data";
165 if (data.size() % 3 == 0 && data.size() <= 48)
166 return "sprite data";
167 if (data.size() == 32)
168 return "palette data (16 colors)";
169 if (data.size() > 1000)
170 return "compressed data block";
171 return "unknown data";
172}
173
174std::vector<std::string> AdvancedRouter::ExtractPatterns(
175 const std::vector<uint8_t>& data) {
176 std::vector<std::string> patterns;
177
178 // Check for repeating bytes
179 if (data.size() > 2) {
180 bool all_same = true;
181 for (size_t i = 1; i < data.size(); ++i) {
182 if (data[i] != data[0]) {
183 all_same = false;
184 break;
185 }
186 }
187 if (all_same) {
188 patterns.push_back(absl::StrFormat("Repeating byte: 0x%02X", data[0]));
189 }
190 }
191
192 // Check for ascending/descending sequences
193 if (data.size() > 3) {
194 bool ascending = true, descending = true;
195 for (size_t i = 1; i < data.size(); ++i) {
196 if (data[i] != data[i - 1] + 1)
197 ascending = false;
198 if (data[i] != data[i - 1] - 1)
199 descending = false;
200 }
201 if (ascending)
202 patterns.push_back("Ascending sequence");
203 if (descending)
204 patterns.push_back("Descending sequence");
205 }
206
207 return patterns;
208}
209
210std::string AdvancedRouter::FormatForAgent(const std::string& raw_data) {
211 // Format data for easy agent consumption
212 return "```\n" + raw_data + "\n```";
213}
214
215} // namespace agent
216} // namespace cli
217} // namespace yaze
static std::string FormatForAgent(const std::string &raw_data)
static RoutedResponse RouteHexAnalysis(const std::vector< uint8_t > &data, uint32_t address, const RouteContext &ctx)
Route hex data analysis response.
static RoutedResponse SynthesizeMultiToolResponse(const std::vector< std::string > &tool_results, const RouteContext &ctx)
Synthesize multi-tool response.
static RoutedResponse RoutePaletteAnalysis(const std::vector< uint16_t > &colors, const RouteContext &ctx)
Route palette analysis response.
static std::vector< std::string > ExtractPatterns(const std::vector< uint8_t > &data)
static std::string GenerateGUIScript(const std::vector< std::string > &actions)
Generate GUI automation script.
static RoutedResponse RouteMapEdit(const std::string &edit_intent, const RouteContext &ctx)
Route map editing response.
static std::string InferDataType(const std::vector< uint8_t > &data)