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:
scawful
2025-10-04 12:00:51 -04:00
parent acada1bec5
commit 4b61b213c0
15 changed files with 844 additions and 68 deletions

View File

@@ -1,6 +1,6 @@
[
{
"name": "resource_list",
"name": "resource-list",
"description": "List all labeled resources of a specific type (dungeons, sprites, palettes)",
"parameters": {
"type": "object",
@@ -8,7 +8,53 @@
"type": {
"type": "string",
"description": "Resource type to list",
"enum": ["dungeon", "sprite", "palette", "all"]
"enum": [
"dungeon",
"room",
"entrance",
"overworld",
"sprite",
"palette",
"item",
"tile16",
"all"
]
},
"format": {
"type": "string",
"description": "Output format",
"enum": ["json", "table", "text"],
"default": "table"
}
},
"required": ["type"]
}
},
{
"name": "resource-search",
"description": "Search labeled resources by name, ID, or partial match",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Search text (case-insensitive substring match)"
},
"type": {
"type": "string",
"description": "Optional resource category to filter",
"enum": [
"dungeon",
"room",
"entrance",
"overworld",
"sprite",
"palette",
"item",
"tile16",
"all"
],
"default": "all"
},
"format": {
"type": "string",
@@ -17,11 +63,11 @@
"default": "json"
}
},
"required": ["type"]
"required": ["query"]
}
},
{
"name": "dungeon_list_sprites",
"name": "dungeon-list-sprites",
"description": "List all sprites in a specific dungeon room",
"parameters": {
"type": "object",
@@ -40,7 +86,26 @@
}
},
{
"name": "overworld_find_tile",
"name": "dungeon-describe-room",
"description": "Summarize dungeon room metadata, hazards, and counts",
"parameters": {
"type": "object",
"properties": {
"room": {
"type": "string",
"description": "Room ID in hex format (e.g., 0x012)"
},
"format": {
"type": "string",
"enum": ["json", "text"],
"default": "json"
}
},
"required": ["room"]
}
},
{
"name": "overworld-find-tile",
"description": "Find all occurrences of a specific tile16 ID on overworld maps",
"parameters": {
"type": "object",
@@ -63,7 +128,7 @@
}
},
{
"name": "overworld_describe_map",
"name": "overworld-describe-map",
"description": "Get summary information about an overworld map",
"parameters": {
"type": "object",
@@ -82,7 +147,7 @@
}
},
{
"name": "overworld_list_warps",
"name": "overworld-list-warps",
"description": "List warp/entrance/exit points on the overworld",
"parameters": {
"type": "object",
@@ -94,7 +159,8 @@
"type": {
"type": "string",
"description": "Optional: filter by warp type",
"enum": ["entrance", "exit", "hole", "all"]
"enum": ["entrance", "exit", "hole", "all"],
"default": "all"
},
"format": {
"type": "string",

View File

@@ -36,16 +36,32 @@ commands:
tools:
- name: resource-list
description: "List project-defined resource labels for the requested category."
usage_notes: "Use this whenever you need to reference project-specific labels or IDs from the ROM. Valid categories are: room, entrance, sprite, overlord, item."
usage_notes: "Use this whenever you need to reference project-specific labels or IDs from the ROM. Valid categories: dungeon, room, entrance, overworld, sprite, palette, item, tile16, or all."
arguments:
- name: type
description: "Resource category. Valid values: room, entrance, sprite, overlord, item."
description: "Resource category. Valid values: dungeon, room, entrance, overworld, sprite, palette, item, tile16, all."
required: true
example: room
example: dungeon
- name: format
description: "Response format (json or table). Defaults to JSON if omitted."
required: false
example: json
- name: resource-search
description: "Search resource labels by partial name or ID."
usage_notes: "Use to locate specific rooms, sprites, palettes, entrances, overworld maps, or tile16 entries based on fuzzy text."
arguments:
- name: query
description: "Search term to match against labels and IDs."
required: true
example: soldier
- name: type
description: "Optional category filter (dungeon, room, entrance, overworld, sprite, palette, item, tile16, all)."
required: false
example: sprite
- name: format
description: "Response format (json or text). Defaults to JSON."
required: false
example: json
- name: dungeon-list-sprites
description: "Inspect sprite placements for a specific dungeon room."
usage_notes: "Returns sprite IDs, positions, and metadata for the requested room."
@@ -62,6 +78,18 @@ tools:
description: "Response format (json or table). Defaults to JSON if omitted."
required: false
example: json
- name: dungeon-describe-room
description: "Summarize dungeon room metadata, hazards, and object counts."
usage_notes: "Great for understanding room state before proposing edits. Includes lighting, effect flags, chests, staircases, and sample sprites."
arguments:
- name: room
description: "Room label or numeric ID (supports hex like 0x123)."
required: true
example: 0x012
- name: format
description: "Response format (json or text). Defaults to JSON if omitted."
required: false
example: json
- name: overworld-find-tile
description: "Search all overworld maps for occurrences of a specific tile16 ID."
usage_notes: "Ideal for tile lookup questions. Includes coordinates for each match."
@@ -188,7 +216,14 @@ examples:
tool_calls:
- tool_name: resource-list
args:
type: room
type: dungeon
- user_prompt: "Search for soldier sprites in the label database"
reasoning: "The user wants to find sprite labels. I should use the `resource-search` tool with a sprite filter."
tool_calls:
- tool_name: resource-search
args:
query: soldier
type: sprite
- user_prompt: "[TOOL RESULT] {\"resources\": [{\"id\": 0, \"label\": \"Ganon\"}, {\"id\": 1, \"label\": \"Hyrule Castle\"}, {\"id\": 2, \"label\": \"Eastern Palace\"}, {\"id\": 3, \"label\": \"Desert Palace\"}, {\"id\": 4, \"label\": \"Tower of Hera\"}, {\"id\": 5, \"label\": \"Palace of Darkness\"}]}"
text_response: "Based on the ROM data, this project contains 297 rooms. The first few include: Ganon's Room, Hyrule Castle, Eastern Palace, Desert Palace, Tower of Hera, and Palace of Darkness."
reasoning: "I received the tool results showing room labels. Now I provide a natural language summary of this information."
@@ -198,6 +233,12 @@ examples:
- tool_name: dungeon-list-sprites
args:
room: "5"
- user_prompt: "Describe dungeon room 0x012"
reasoning: "The user wants overall room metadata. I should call `dungeon-describe-room` to gather the summary."
tool_calls:
- tool_name: dungeon-describe-room
args:
room: "0x012"
- user_prompt: "[TOOL RESULT] {\"sprites\": [{\"id\": 0x41, \"name\": \"soldier\", \"x\": 5, \"y\": 3}, {\"id\": 0x41, \"name\": \"soldier\", \"x\": 10, \"y\": 3}]}"
text_response: "Room 5 contains 2 sprites: two soldiers positioned at coordinates (5, 3) and (10, 3). Both are sprite ID 0x41."
reasoning: "The tool returned sprite data for room 5. I've formatted this into a readable response for the user."