feat: Add resource search and dungeon room description commands
- Implemented `resource-search` command to allow fuzzy searching of resource labels. - Added `dungeon-describe-room` command to summarize metadata for a specified dungeon room. - Enhanced `agent` command handler to support new commands and updated usage documentation. - Introduced read-only accessors for room metadata in the Room class. - Updated AI service to recognize and handle new commands for resource searching and room description. - Improved metrics tracking for user interactions, including command execution and response times. - Enhanced TUI to display command metrics and session summaries.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <sstream>
|
||||
|
||||
#include "absl/strings/ascii.h"
|
||||
#include "absl/strings/match.h"
|
||||
@@ -51,6 +52,38 @@ std::string ExtractRoomId(const std::string& normalized_prompt) {
|
||||
return "0x000";
|
||||
}
|
||||
|
||||
std::string ExtractKeyword(const std::string& normalized_prompt) {
|
||||
static const char* kStopwords[] = {
|
||||
"search", "for", "resource", "resources", "label", "labels",
|
||||
"please", "the", "a", "an", "list", "of", "in", "find"};
|
||||
|
||||
auto is_stopword = [](const std::string& word) {
|
||||
for (const char* stop : kStopwords) {
|
||||
if (word == stop) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
std::istringstream stream(normalized_prompt);
|
||||
std::string token;
|
||||
while (stream >> token) {
|
||||
token.erase(std::remove_if(token.begin(), token.end(), [](unsigned char c) {
|
||||
return !std::isalnum(c) && c != '_' && c != '-';
|
||||
}),
|
||||
token.end());
|
||||
if (token.empty()) {
|
||||
continue;
|
||||
}
|
||||
if (!is_stopword(token)) {
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
||||
return "all";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
absl::StatusOr<AgentResponse> MockAIService::GenerateResponse(
|
||||
@@ -96,6 +129,20 @@ absl::StatusOr<AgentResponse> MockAIService::GenerateResponse(
|
||||
return response;
|
||||
}
|
||||
|
||||
if (absl::StrContains(normalized, "search") &&
|
||||
(absl::StrContains(normalized, "resource") ||
|
||||
absl::StrContains(normalized, "label"))) {
|
||||
ToolCall call;
|
||||
call.tool_name = "resource-search";
|
||||
call.args.emplace("query", ExtractKeyword(normalized));
|
||||
response.text_response =
|
||||
"Let me look through the labelled resources for matches.";
|
||||
response.reasoning =
|
||||
"Resource search provides fuzzy matching against the ROM label catalogue.";
|
||||
response.tool_calls.push_back(call);
|
||||
return response;
|
||||
}
|
||||
|
||||
if (absl::StrContains(normalized, "sprite") &&
|
||||
absl::StrContains(normalized, "room")) {
|
||||
ToolCall call;
|
||||
@@ -109,6 +156,19 @@ absl::StatusOr<AgentResponse> MockAIService::GenerateResponse(
|
||||
return response;
|
||||
}
|
||||
|
||||
if (absl::StrContains(normalized, "describe") &&
|
||||
absl::StrContains(normalized, "room")) {
|
||||
ToolCall call;
|
||||
call.tool_name = "dungeon-describe-room";
|
||||
call.args.emplace("room", ExtractRoomId(normalized));
|
||||
response.text_response =
|
||||
"I'll summarize the room's metadata and hazards.";
|
||||
response.reasoning =
|
||||
"Room description tool surfaces lighting, effects, and object counts before planning edits.";
|
||||
response.tool_calls.push_back(call);
|
||||
return response;
|
||||
}
|
||||
|
||||
response.text_response =
|
||||
"I'm just a mock service. Please load a provider like ollama or gemini.";
|
||||
return response;
|
||||
|
||||
@@ -123,11 +123,13 @@ void GeminiAIService::EnableFunctionCalling(bool enable) {
|
||||
|
||||
std::vector<std::string> GeminiAIService::GetAvailableTools() const {
|
||||
return {
|
||||
"resource_list",
|
||||
"dungeon_list_sprites",
|
||||
"overworld_find_tile",
|
||||
"overworld_describe_map",
|
||||
"overworld_list_warps"
|
||||
"resource-list",
|
||||
"resource-search",
|
||||
"dungeon-list-sprites",
|
||||
"dungeon-describe-room",
|
||||
"overworld-find-tile",
|
||||
"overworld-describe-map",
|
||||
"overworld-list-warps"
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user