93 const std::string& prompt) {
99 const std::string normalized = absl::AsciiStrToLower(prompt);
101 if (normalized.empty()) {
103 "Let's start with a prompt about the overworld or dungeons.";
107 if (absl::StrContains(normalized,
"place") &&
108 absl::StrContains(normalized,
"tree")) {
110 "Sure, I can do that. Here's the command to place a tree.";
112 "overworld set-tile --map 0 --x 10 --y 20 --tile 0x02E");
114 "The user asked to place a tree tile16, so I generated the matching "
119 if (absl::StrContains(normalized,
"list") &&
120 absl::StrContains(normalized,
"resource")) {
121 std::string resource_type =
"dungeon";
122 if (absl::StrContains(normalized,
"overworld")) {
123 resource_type =
"overworld";
124 }
else if (absl::StrContains(normalized,
"sprite")) {
125 resource_type =
"sprite";
126 }
else if (absl::StrContains(normalized,
"palette")) {
127 resource_type =
"palette";
132 call.
args.emplace(
"type", resource_type);
134 absl::StrFormat(
"Fetching %s labels from the ROM...", resource_type);
136 "Using the resource-list tool keeps the LLM in sync with project "
142 if (absl::StrContains(normalized,
"search") &&
143 (absl::StrContains(normalized,
"resource") ||
144 absl::StrContains(normalized,
"label"))) {
147 call.
args.emplace(
"query", ExtractKeyword(normalized));
149 "Let me look through the labelled resources for matches.";
151 "Resource search provides fuzzy matching against the ROM label "
157 if (absl::StrContains(normalized,
"sprite") &&
158 absl::StrContains(normalized,
"room")) {
161 call.
args.emplace(
"room", ExtractRoomId(normalized));
162 response.
text_response =
"Let me inspect the dungeon room sprites for you.";
164 "Calling the sprite inspection tool provides precise coordinates for "
170 if (absl::StrContains(normalized,
"describe") &&
171 absl::StrContains(normalized,
"room")) {
173 call.
tool_name =
"dungeon-describe-room";
174 call.
args.emplace(
"room", ExtractRoomId(normalized));
175 response.
text_response =
"I'll summarize the room's metadata and hazards.";
177 "Room description tool surfaces lighting, effects, and object counts "
178 "before planning edits.";
184 "I'm just a mock service. Please load a provider like ollama or gemini.";
189 const std::vector<agent::ChatMessage>& history) {
190 if (history.empty()) {
191 return absl::InvalidArgumentError(
"History cannot be empty.");
195 for (
auto it = history.rbegin(); it != history.rend(); ++it) {
197 (absl::StrContains(it->message,
"=== ") ||
198 absl::StrContains(it->message,
"\"id\"") ||
199 absl::StrContains(it->message,
"\n{"))) {
205 response.
text_response =
"Here's what I found:\n" + it->message +
206 "\nLet me know if you'd like to make a change.";
207 response.
reasoning =
"Summarized the latest tool output for the user.";
212 auto user_it = std::find_if(
214 return message.sender == agent::ChatMessage::Sender::kUser;
216 if (user_it == history.rend()) {
217 return absl::InvalidArgumentError(
218 "History does not contain a user message.");