92 const std::string& prompt) {
95 response.
model =
"mock";
98 const std::string normalized = absl::AsciiStrToLower(prompt);
100 if (normalized.empty()) {
102 "Let's start with a prompt about the overworld or dungeons.";
106 if (absl::StrContains(normalized,
"place") &&
107 absl::StrContains(normalized,
"tree")) {
109 "Sure, I can do that. Here's the command to place a tree.";
111 "overworld set-tile --map 0 --x 10 --y 20 --tile 0x02E");
113 "The user asked to place a tree tile16, so I generated the matching "
118 if (absl::StrContains(normalized,
"list") &&
119 absl::StrContains(normalized,
"resource")) {
120 std::string resource_type =
"dungeon";
121 if (absl::StrContains(normalized,
"overworld")) {
122 resource_type =
"overworld";
123 }
else if (absl::StrContains(normalized,
"sprite")) {
124 resource_type =
"sprite";
125 }
else if (absl::StrContains(normalized,
"palette")) {
126 resource_type =
"palette";
131 call.
args.emplace(
"type", resource_type);
133 absl::StrFormat(
"Fetching %s labels from the ROM...", resource_type);
135 "Using the resource-list tool keeps the LLM in sync with project "
141 if (absl::StrContains(normalized,
"search") &&
142 (absl::StrContains(normalized,
"resource") ||
143 absl::StrContains(normalized,
"label"))) {
146 call.
args.emplace(
"query", ExtractKeyword(normalized));
148 "Let me look through the labelled resources for matches.";
150 "Resource search provides fuzzy matching against the ROM label "
156 if (absl::StrContains(normalized,
"sprite") &&
157 absl::StrContains(normalized,
"room")) {
160 call.
args.emplace(
"room", ExtractRoomId(normalized));
161 response.
text_response =
"Let me inspect the dungeon room sprites for you.";
163 "Calling the sprite inspection tool provides precise coordinates for "
169 if (absl::StrContains(normalized,
"describe") &&
170 absl::StrContains(normalized,
"room")) {
172 call.
tool_name =
"dungeon-describe-room";
173 call.
args.emplace(
"room", ExtractRoomId(normalized));
174 response.
text_response =
"I'll summarize the room's metadata and hazards.";
176 "Room description tool surfaces lighting, effects, and object counts "
177 "before planning edits.";
183 "I'm just a mock service. Please load a provider like ollama or gemini.";
188 const std::vector<agent::ChatMessage>& history) {
189 if (history.empty()) {
190 return absl::InvalidArgumentError(
"History cannot be empty.");
194 for (
auto it = history.rbegin(); it != history.rend(); ++it) {
196 (absl::StrContains(it->message,
"=== ") ||
197 absl::StrContains(it->message,
"\"id\"") ||
198 absl::StrContains(it->message,
"\n{"))) {
201 response.
model =
"mock";
204 response.
text_response =
"Here's what I found:\n" + it->message +
205 "\nLet me know if you'd like to make a change.";
206 response.
reasoning =
"Summarized the latest tool output for the user.";
211 auto user_it = std::find_if(
213 return message.sender == agent::ChatMessage::Sender::kUser;
215 if (user_it == history.rend()) {
216 return absl::InvalidArgumentError(
217 "History does not contain a user message.");