40 return absl::InvalidArgumentError(
"Agent response is required");
42 if (request.
rom ==
nullptr) {
43 return absl::InvalidArgumentError(
"ROM context is required");
46 return absl::FailedPreconditionError(
47 "ROM must be loaded before creating proposals");
50 return absl::InvalidArgumentError(
51 "Agent response did not contain any commands to execute");
57 if (!sandbox_or.ok()) {
58 return sandbox_or.status();
60 auto sandbox = sandbox_or.value();
78 int executed_commands = 0;
80 if (IsExecutableCommand(command)) {
85 std::string description = absl::StrFormat(
86 "Tile16 overworld edits (%d change%s)", proposal.changes.size(),
87 proposal.changes.size() == 1 ?
"" :
"s");
90 registry.CreateProposal(sandbox.id, sandbox.rom_path,
91 request.
prompt, description));
93 proposal.id = metadata.id;
95 std::ostringstream diff_stream;
96 diff_stream <<
"Tile16 Proposal ID: " << metadata.id <<
"\n";
97 diff_stream <<
"Sandbox ID: " << sandbox.id <<
"\n";
98 diff_stream <<
"Sandbox ROM: " << sandbox.rom_path <<
"\n\n";
99 diff_stream <<
"Changes (" << proposal.changes.size() <<
"):\n";
100 for (
const auto& change : proposal.changes) {
101 diff_stream <<
" - " << change.ToString() <<
"\n";
107 metadata.id, absl::StrCat(
"Prompt: ", request.
prompt)));
122 std::vector<std::string> call_summaries;
125 std::vector<std::string> args;
126 for (
const auto& [key, value] : tool_call.args) {
127 args.push_back(absl::StrCat(key,
"=", value));
129 call_summaries.push_back(absl::StrCat(
130 tool_call.tool_name,
"(", absl::StrJoin(args,
", "),
")"));
134 absl::StrCat(
"Tool Calls (", call_summaries.size(),
"): ",
135 absl::StrJoin(call_summaries,
"; "))));
139 if (!IsExecutableCommand(command)) {
143 metadata.id, absl::StrCat(
"Command: ", command)));
148 absl::StrCat(
"Sandbox ROM saved to ", sandbox.rom_path.string())));
151 registry.UpdateCommandStats(metadata.id, executed_commands));
154 absl::StrCat(
"Commands executed: ", executed_commands)));
156 std::filesystem::path proposal_dir = metadata.log_path.parent_path();
157 std::filesystem::path proposal_path = proposal_dir /
"proposal.json";
162 absl::StrCat(
"Saved proposal JSON to ", proposal_path.string())));
166 metadata.id, absl::StrCat(
"AI Provider: ", request.
ai_provider)));
170 registry.GetProposal(metadata.id));
173 result.
metadata = std::move(refreshed_metadata);
176 result.
change_count =
static_cast<int>(proposal.changes.size());
absl::StatusOr< Tile16Proposal > GenerateFromCommands(const std::string &prompt, const std::vector< std::string > &commands, const std::string &ai_service, Rom *rom)
Generate a tile16 proposal from an AI-generated command list.