feat: Add PromptBuilder for enhanced command prompting and examples
This commit is contained in:
@@ -19,30 +19,23 @@ namespace cli {
|
|||||||
|
|
||||||
GeminiAIService::GeminiAIService(const GeminiConfig& config)
|
GeminiAIService::GeminiAIService(const GeminiConfig& config)
|
||||||
: config_(config) {
|
: config_(config) {
|
||||||
|
// Load command documentation into prompt builder
|
||||||
|
prompt_builder_.LoadResourceCatalogue(""); // TODO: Pass actual yaml path when available
|
||||||
|
|
||||||
if (config_.system_instruction.empty()) {
|
if (config_.system_instruction.empty()) {
|
||||||
config_.system_instruction = BuildSystemInstruction();
|
// Use enhanced prompting by default
|
||||||
|
if (config_.use_enhanced_prompting) {
|
||||||
|
config_.system_instruction = prompt_builder_.BuildSystemInstructionWithExamples();
|
||||||
|
} else {
|
||||||
|
config_.system_instruction = BuildSystemInstruction();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GeminiAIService::BuildSystemInstruction() {
|
std::string GeminiAIService::BuildSystemInstruction() {
|
||||||
return R"(You are an expert ROM hacking assistant for The Legend of Zelda: A Link to the Past.
|
// Fallback prompt if enhanced prompting is disabled
|
||||||
|
// Use PromptBuilder's basic system instruction
|
||||||
Your task is to generate a sequence of z3ed CLI commands to achieve the user's request.
|
return prompt_builder_.BuildSystemInstruction();
|
||||||
|
|
||||||
CRITICAL: Respond ONLY with a JSON array of strings. Each string must be a complete z3ed command.
|
|
||||||
|
|
||||||
Available z3ed commands:
|
|
||||||
- palette export --group <group> --id <id> --to <file>
|
|
||||||
- palette import --group <group> --id <id> --from <file>
|
|
||||||
- palette set-color --file <file> --index <index> --color <hex_color>
|
|
||||||
- overworld set-tile --map <map_id> --x <x> --y <y> --tile <tile_id>
|
|
||||||
- sprite set-position --id <id> --x <x> --y <y>
|
|
||||||
- dungeon set-room-tile --room <room_id> --x <x> --y <y> --tile <tile_id>
|
|
||||||
|
|
||||||
Example response format:
|
|
||||||
["z3ed palette export --group overworld --id 0 --to palette.json", "z3ed palette set-color --file palette.json --index 5 --color 0xFF0000"]
|
|
||||||
|
|
||||||
Do not include explanations, markdown formatting, or code blocks. Only the JSON array.)";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status GeminiAIService::CheckAvailability() {
|
absl::Status GeminiAIService::CheckAvailability() {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
#include "absl/status/statusor.h"
|
#include "absl/status/statusor.h"
|
||||||
#include "cli/service/ai_service.h"
|
#include "cli/service/ai_service.h"
|
||||||
|
#include "cli/service/prompt_builder.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace cli {
|
namespace cli {
|
||||||
@@ -17,6 +18,7 @@ struct GeminiConfig {
|
|||||||
float temperature = 0.7f;
|
float temperature = 0.7f;
|
||||||
int max_output_tokens = 2048;
|
int max_output_tokens = 2048;
|
||||||
std::string system_instruction;
|
std::string system_instruction;
|
||||||
|
bool use_enhanced_prompting = true; // Enable few-shot examples
|
||||||
|
|
||||||
GeminiConfig() = default;
|
GeminiConfig() = default;
|
||||||
explicit GeminiConfig(const std::string& key) : api_key(key) {}
|
explicit GeminiConfig(const std::string& key) : api_key(key) {}
|
||||||
@@ -39,6 +41,7 @@ class GeminiAIService : public AIService {
|
|||||||
const std::string& response_body);
|
const std::string& response_body);
|
||||||
|
|
||||||
GeminiConfig config_;
|
GeminiConfig config_;
|
||||||
|
PromptBuilder prompt_builder_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace cli
|
} // namespace cli
|
||||||
|
|||||||
@@ -31,52 +31,23 @@ namespace yaze {
|
|||||||
namespace cli {
|
namespace cli {
|
||||||
|
|
||||||
OllamaAIService::OllamaAIService(const OllamaConfig& config) : config_(config) {
|
OllamaAIService::OllamaAIService(const OllamaConfig& config) : config_(config) {
|
||||||
|
// Load command documentation into prompt builder
|
||||||
|
prompt_builder_.LoadResourceCatalogue(""); // TODO: Pass actual yaml path when available
|
||||||
|
|
||||||
if (config_.system_prompt.empty()) {
|
if (config_.system_prompt.empty()) {
|
||||||
config_.system_prompt = BuildSystemPrompt();
|
// Use enhanced prompting by default
|
||||||
|
if (config_.use_enhanced_prompting) {
|
||||||
|
config_.system_prompt = prompt_builder_.BuildSystemInstructionWithExamples();
|
||||||
|
} else {
|
||||||
|
config_.system_prompt = BuildSystemPrompt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string OllamaAIService::BuildSystemPrompt() {
|
std::string OllamaAIService::BuildSystemPrompt() {
|
||||||
// TODO: Eventually load from docs/api/z3ed-resources.yaml for full command catalogue
|
// Fallback prompt if enhanced prompting is disabled
|
||||||
// For now, use a comprehensive hardcoded prompt
|
// Use PromptBuilder's basic system instruction
|
||||||
return R"(You are an expert ROM hacking assistant for The Legend of Zelda: A Link to the Past.
|
return prompt_builder_.BuildSystemInstruction();
|
||||||
Your role is to generate PRECISE z3ed CLI commands to fulfill user requests.
|
|
||||||
|
|
||||||
CRITICAL RULES:
|
|
||||||
1. Output ONLY a JSON array of command strings
|
|
||||||
2. Each command must follow exact z3ed syntax
|
|
||||||
3. Commands must be executable without modification
|
|
||||||
4. Use only commands from the available command set
|
|
||||||
5. Include all required arguments with proper flags
|
|
||||||
|
|
||||||
AVAILABLE COMMANDS:
|
|
||||||
- rom info --rom <path>
|
|
||||||
- rom validate --rom <path>
|
|
||||||
- rom diff --rom1 <path1> --rom2 <path2>
|
|
||||||
- palette export --group <group> --id <id> --to <file>
|
|
||||||
- palette import --group <group> --id <id> --from <file>
|
|
||||||
- palette set-color --file <file> --index <index> --color <hex_color>
|
|
||||||
- overworld get-tile --map <map_id> --x <x> --y <y>
|
|
||||||
- overworld set-tile --map <map_id> --x <x> --y <y> --tile <tile_id>
|
|
||||||
- dungeon export-room --room <room_id> --to <file>
|
|
||||||
- dungeon import-room --room <room_id> --from <file>
|
|
||||||
|
|
||||||
RESPONSE FORMAT:
|
|
||||||
["command1", "command2", "command3"]
|
|
||||||
|
|
||||||
EXAMPLE 1:
|
|
||||||
User: "Validate the ROM"
|
|
||||||
Response: ["rom validate --rom zelda3.sfc"]
|
|
||||||
|
|
||||||
EXAMPLE 2:
|
|
||||||
User: "Make all soldier armors red"
|
|
||||||
Response: ["palette export --group sprites --id soldier --to /tmp/soldier.pal", "palette set-color --file /tmp/soldier.pal --index 5 --color FF0000", "palette import --group sprites --id soldier --from /tmp/soldier.pal"]
|
|
||||||
|
|
||||||
EXAMPLE 3:
|
|
||||||
User: "Export the first overworld palette"
|
|
||||||
Response: ["palette export --group overworld --id 0 --to /tmp/ow_pal_0.pal"]
|
|
||||||
|
|
||||||
Begin your response now.)";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status OllamaAIService::CheckAvailability() {
|
absl::Status OllamaAIService::CheckAvailability() {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
#include "absl/status/statusor.h"
|
#include "absl/status/statusor.h"
|
||||||
#include "cli/service/ai_service.h"
|
#include "cli/service/ai_service.h"
|
||||||
|
#include "cli/service/prompt_builder.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace cli {
|
namespace cli {
|
||||||
@@ -18,6 +19,7 @@ struct OllamaConfig {
|
|||||||
float temperature = 0.1; // Low temp for deterministic commands
|
float temperature = 0.1; // Low temp for deterministic commands
|
||||||
int max_tokens = 2048; // Sufficient for command lists
|
int max_tokens = 2048; // Sufficient for command lists
|
||||||
std::string system_prompt; // Injected from resource catalogue
|
std::string system_prompt; // Injected from resource catalogue
|
||||||
|
bool use_enhanced_prompting = true; // Enable few-shot examples
|
||||||
};
|
};
|
||||||
|
|
||||||
class OllamaAIService : public AIService {
|
class OllamaAIService : public AIService {
|
||||||
@@ -36,6 +38,7 @@ class OllamaAIService : public AIService {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
OllamaConfig config_;
|
OllamaConfig config_;
|
||||||
|
PromptBuilder prompt_builder_;
|
||||||
|
|
||||||
// Build system prompt from resource catalogue
|
// Build system prompt from resource catalogue
|
||||||
std::string BuildSystemPrompt();
|
std::string BuildSystemPrompt();
|
||||||
|
|||||||
300
src/cli/service/prompt_builder.cc
Normal file
300
src/cli/service/prompt_builder.cc
Normal file
@@ -0,0 +1,300 @@
|
|||||||
|
#include "cli/service/prompt_builder.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "absl/strings/str_cat.h"
|
||||||
|
#include "absl/strings/str_join.h"
|
||||||
|
|
||||||
|
namespace yaze {
|
||||||
|
namespace cli {
|
||||||
|
|
||||||
|
PromptBuilder::PromptBuilder() {
|
||||||
|
LoadDefaultExamples();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PromptBuilder::LoadDefaultExamples() {
|
||||||
|
// Palette manipulation examples
|
||||||
|
examples_.push_back({
|
||||||
|
"Change the color at index 5 in palette 0 to red",
|
||||||
|
{
|
||||||
|
"palette export --group overworld --id 0 --to temp_palette.json",
|
||||||
|
"palette set-color --file temp_palette.json --index 5 --color 0xFF0000",
|
||||||
|
"palette import --group overworld --id 0 --from temp_palette.json"
|
||||||
|
},
|
||||||
|
"Export palette, modify specific color, then import back"
|
||||||
|
});
|
||||||
|
|
||||||
|
examples_.push_back({
|
||||||
|
"Make all soldiers red",
|
||||||
|
{
|
||||||
|
"palette export --group sprite --id 3 --to soldier_palette.json",
|
||||||
|
"palette set-color --file soldier_palette.json --index 1 --color 0xFF0000",
|
||||||
|
"palette set-color --file soldier_palette.json --index 2 --color 0xCC0000",
|
||||||
|
"palette import --group sprite --id 3 --from soldier_palette.json"
|
||||||
|
},
|
||||||
|
"Modify multiple colors in a sprite palette"
|
||||||
|
});
|
||||||
|
|
||||||
|
// Overworld manipulation examples
|
||||||
|
examples_.push_back({
|
||||||
|
"Place a tree at coordinates (10, 20) on map 0",
|
||||||
|
{
|
||||||
|
"overworld set-tile --map 0 --x 10 --y 20 --tile 0x02E"
|
||||||
|
},
|
||||||
|
"Tree tile ID is 0x02E in ALTTP"
|
||||||
|
});
|
||||||
|
|
||||||
|
examples_.push_back({
|
||||||
|
"Put a house at position 5, 5",
|
||||||
|
{
|
||||||
|
"overworld set-tile --map 0 --x 5 --y 5 --tile 0x0C0",
|
||||||
|
"overworld set-tile --map 0 --x 6 --y 5 --tile 0x0C1",
|
||||||
|
"overworld set-tile --map 0 --x 5 --y 6 --tile 0x0D0",
|
||||||
|
"overworld set-tile --map 0 --x 6 --y 6 --tile 0x0D1"
|
||||||
|
},
|
||||||
|
"Houses require 4 tiles (2x2 grid)"
|
||||||
|
});
|
||||||
|
|
||||||
|
// Validation examples
|
||||||
|
examples_.push_back({
|
||||||
|
"Validate the ROM",
|
||||||
|
{
|
||||||
|
"rom validate"
|
||||||
|
},
|
||||||
|
"Simple validation command"
|
||||||
|
});
|
||||||
|
|
||||||
|
examples_.push_back({
|
||||||
|
"Check if my changes are valid",
|
||||||
|
{
|
||||||
|
"rom validate"
|
||||||
|
},
|
||||||
|
"Validation ensures ROM integrity"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::Status PromptBuilder::LoadResourceCatalogue(const std::string& yaml_path) {
|
||||||
|
// TODO: Parse z3ed-resources.yaml when available
|
||||||
|
// For now, use hardcoded command reference
|
||||||
|
|
||||||
|
command_docs_["palette export"] =
|
||||||
|
"Export palette data to JSON file\n"
|
||||||
|
" --group <group> Palette group (overworld, dungeon, sprite)\n"
|
||||||
|
" --id <id> Palette ID (0-based index)\n"
|
||||||
|
" --to <file> Output JSON file path";
|
||||||
|
|
||||||
|
command_docs_["palette import"] =
|
||||||
|
"Import palette data from JSON file\n"
|
||||||
|
" --group <group> Palette group (overworld, dungeon, sprite)\n"
|
||||||
|
" --id <id> Palette ID (0-based index)\n"
|
||||||
|
" --from <file> Input JSON file path";
|
||||||
|
|
||||||
|
command_docs_["palette set-color"] =
|
||||||
|
"Modify a color in palette JSON file\n"
|
||||||
|
" --file <file> Palette JSON file to modify\n"
|
||||||
|
" --index <index> Color index (0-15 per palette)\n"
|
||||||
|
" --color <hex> New color in hex (0xRRGGBB format)";
|
||||||
|
|
||||||
|
command_docs_["overworld set-tile"] =
|
||||||
|
"Place a tile in the overworld\n"
|
||||||
|
" --map <id> Map ID (0-based)\n"
|
||||||
|
" --x <x> X coordinate (0-63)\n"
|
||||||
|
" --y <y> Y coordinate (0-63)\n"
|
||||||
|
" --tile <hex> Tile ID in hex (e.g., 0x02E for tree)";
|
||||||
|
|
||||||
|
command_docs_["sprite set-position"] =
|
||||||
|
"Move a sprite to new position\n"
|
||||||
|
" --id <id> Sprite ID\n"
|
||||||
|
" --x <x> X coordinate\n"
|
||||||
|
" --y <y> Y coordinate";
|
||||||
|
|
||||||
|
command_docs_["dungeon set-room-tile"] =
|
||||||
|
"Place a tile in dungeon room\n"
|
||||||
|
" --room <id> Room ID\n"
|
||||||
|
" --x <x> X coordinate\n"
|
||||||
|
" --y <y> Y coordinate\n"
|
||||||
|
" --tile <hex> Tile ID";
|
||||||
|
|
||||||
|
command_docs_["rom validate"] =
|
||||||
|
"Validate ROM integrity and structure";
|
||||||
|
|
||||||
|
catalogue_loaded_ = true;
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PromptBuilder::BuildCommandReference() {
|
||||||
|
std::ostringstream oss;
|
||||||
|
|
||||||
|
oss << "# Available z3ed Commands\n\n";
|
||||||
|
|
||||||
|
for (const auto& [cmd, docs] : command_docs_) {
|
||||||
|
oss << "## " << cmd << "\n";
|
||||||
|
oss << docs << "\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PromptBuilder::BuildFewShotExamplesSection() {
|
||||||
|
std::ostringstream oss;
|
||||||
|
|
||||||
|
oss << "# Example Command Sequences\n\n";
|
||||||
|
oss << "Here are proven examples of how to accomplish common tasks:\n\n";
|
||||||
|
|
||||||
|
for (const auto& example : examples_) {
|
||||||
|
oss << "**User Request:** \"" << example.user_prompt << "\"\n";
|
||||||
|
oss << "**Commands:**\n";
|
||||||
|
oss << "```json\n[";
|
||||||
|
|
||||||
|
std::vector<std::string> quoted_cmds;
|
||||||
|
for (const auto& cmd : example.expected_commands) {
|
||||||
|
quoted_cmds.push_back("\"" + cmd + "\"");
|
||||||
|
}
|
||||||
|
oss << absl::StrJoin(quoted_cmds, ", ");
|
||||||
|
|
||||||
|
oss << "]\n```\n";
|
||||||
|
oss << "*Explanation:* " << example.explanation << "\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PromptBuilder::BuildConstraintsSection() {
|
||||||
|
return R"(
|
||||||
|
# Critical Constraints
|
||||||
|
|
||||||
|
1. **Output Format:** You MUST respond with ONLY a JSON array of strings
|
||||||
|
- Each string is a complete z3ed command
|
||||||
|
- NO explanatory text before or after
|
||||||
|
- NO markdown code blocks (```json)
|
||||||
|
- NO "z3ed" prefix in commands
|
||||||
|
|
||||||
|
2. **Command Syntax:** Follow the exact syntax shown in examples
|
||||||
|
- Use correct flag names (--group, --id, --to, --from, etc.)
|
||||||
|
- Use hex format for colors (0xRRGGBB) and tile IDs (0xNNN)
|
||||||
|
- Coordinates are 0-based indices
|
||||||
|
|
||||||
|
3. **Common Patterns:**
|
||||||
|
- Palette modifications: export → set-color → import
|
||||||
|
- Multiple tile placement: multiple overworld set-tile commands
|
||||||
|
- Validation: single rom validate command
|
||||||
|
|
||||||
|
4. **Tile IDs Reference (ALTTP):**
|
||||||
|
- Tree: 0x02E
|
||||||
|
- House (2x2): 0x0C0, 0x0C1, 0x0D0, 0x0D1
|
||||||
|
- Water: 0x038
|
||||||
|
- Grass: 0x000
|
||||||
|
|
||||||
|
5. **Error Prevention:**
|
||||||
|
- Always export before modifying palettes
|
||||||
|
- Use temporary file names (temp_*.json) for intermediate files
|
||||||
|
- Validate coordinates are within bounds
|
||||||
|
)";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PromptBuilder::BuildContextSection(const RomContext& context) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
|
||||||
|
oss << "# Current ROM Context\n\n";
|
||||||
|
|
||||||
|
if (context.rom_loaded) {
|
||||||
|
oss << "- **ROM Loaded:** Yes (" << context.rom_path << ")\n";
|
||||||
|
} else {
|
||||||
|
oss << "- **ROM Loaded:** No\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!context.current_editor.empty()) {
|
||||||
|
oss << "- **Active Editor:** " << context.current_editor << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!context.editor_state.empty()) {
|
||||||
|
oss << "- **Editor State:**\n";
|
||||||
|
for (const auto& [key, value] : context.editor_state) {
|
||||||
|
oss << " - " << key << ": " << value << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oss << "\n";
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PromptBuilder::BuildSystemInstruction() {
|
||||||
|
std::ostringstream oss;
|
||||||
|
|
||||||
|
oss << "You are an expert ROM hacking assistant for The Legend of Zelda: "
|
||||||
|
<< "A Link to the Past (ALTTP).\n\n";
|
||||||
|
|
||||||
|
oss << "Your task is to generate a sequence of z3ed CLI commands to achieve "
|
||||||
|
<< "the user's request.\n\n";
|
||||||
|
|
||||||
|
if (catalogue_loaded_) {
|
||||||
|
oss << BuildCommandReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
oss << BuildConstraintsSection();
|
||||||
|
|
||||||
|
oss << "\n**Response Format:**\n";
|
||||||
|
oss << "```json\n";
|
||||||
|
oss << "[\"command1 --flag value\", \"command2 --flag value\"]\n";
|
||||||
|
oss << "```\n";
|
||||||
|
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PromptBuilder::BuildSystemInstructionWithExamples() {
|
||||||
|
std::ostringstream oss;
|
||||||
|
|
||||||
|
oss << BuildSystemInstruction();
|
||||||
|
oss << "\n---\n\n";
|
||||||
|
oss << BuildFewShotExamplesSection();
|
||||||
|
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PromptBuilder::BuildContextualPrompt(
|
||||||
|
const std::string& user_prompt,
|
||||||
|
const RomContext& context) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
|
||||||
|
if (context.rom_loaded || !context.current_editor.empty()) {
|
||||||
|
oss << BuildContextSection(context);
|
||||||
|
oss << "---\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
oss << "**User Request:** " << user_prompt << "\n\n";
|
||||||
|
oss << "Generate the appropriate z3ed commands as a JSON array.";
|
||||||
|
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PromptBuilder::AddFewShotExample(const FewShotExample& example) {
|
||||||
|
examples_.push_back(example);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<FewShotExample> PromptBuilder::GetExamplesForCategory(
|
||||||
|
const std::string& category) {
|
||||||
|
std::vector<FewShotExample> result;
|
||||||
|
|
||||||
|
for (const auto& example : examples_) {
|
||||||
|
// Simple category matching based on keywords
|
||||||
|
if (category == "palette" &&
|
||||||
|
(example.user_prompt.find("palette") != std::string::npos ||
|
||||||
|
example.user_prompt.find("color") != std::string::npos)) {
|
||||||
|
result.push_back(example);
|
||||||
|
} else if (category == "overworld" &&
|
||||||
|
(example.user_prompt.find("place") != std::string::npos ||
|
||||||
|
example.user_prompt.find("tree") != std::string::npos ||
|
||||||
|
example.user_prompt.find("house") != std::string::npos)) {
|
||||||
|
result.push_back(example);
|
||||||
|
} else if (category == "validation" &&
|
||||||
|
example.user_prompt.find("validate") != std::string::npos) {
|
||||||
|
result.push_back(example);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cli
|
||||||
|
} // namespace yaze
|
||||||
74
src/cli/service/prompt_builder.h
Normal file
74
src/cli/service/prompt_builder.h
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
#ifndef YAZE_CLI_SERVICE_PROMPT_BUILDER_H_
|
||||||
|
#define YAZE_CLI_SERVICE_PROMPT_BUILDER_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
|
|
||||||
|
namespace yaze {
|
||||||
|
namespace cli {
|
||||||
|
|
||||||
|
// Few-shot example for prompt engineering
|
||||||
|
struct FewShotExample {
|
||||||
|
std::string user_prompt;
|
||||||
|
std::vector<std::string> expected_commands;
|
||||||
|
std::string explanation; // Why these commands work
|
||||||
|
};
|
||||||
|
|
||||||
|
// ROM context information to inject into prompts
|
||||||
|
struct RomContext {
|
||||||
|
std::string rom_path;
|
||||||
|
bool rom_loaded = false;
|
||||||
|
std::string current_editor; // "overworld", "dungeon", "sprite", etc.
|
||||||
|
std::map<std::string, std::string> editor_state; // Context-specific state
|
||||||
|
};
|
||||||
|
|
||||||
|
// Builds sophisticated prompts for LLM services
|
||||||
|
class PromptBuilder {
|
||||||
|
public:
|
||||||
|
PromptBuilder();
|
||||||
|
|
||||||
|
// Load z3ed command documentation from resources
|
||||||
|
absl::Status LoadResourceCatalogue(const std::string& yaml_path);
|
||||||
|
|
||||||
|
// Build system instruction with full command reference
|
||||||
|
std::string BuildSystemInstruction();
|
||||||
|
|
||||||
|
// Build system instruction with few-shot examples
|
||||||
|
std::string BuildSystemInstructionWithExamples();
|
||||||
|
|
||||||
|
// Build user prompt with ROM context
|
||||||
|
std::string BuildContextualPrompt(
|
||||||
|
const std::string& user_prompt,
|
||||||
|
const RomContext& context);
|
||||||
|
|
||||||
|
// Add custom few-shot examples
|
||||||
|
void AddFewShotExample(const FewShotExample& example);
|
||||||
|
|
||||||
|
// Get few-shot examples for specific category
|
||||||
|
std::vector<FewShotExample> GetExamplesForCategory(
|
||||||
|
const std::string& category);
|
||||||
|
|
||||||
|
// Set verbosity level (0=minimal, 1=standard, 2=verbose)
|
||||||
|
void SetVerbosity(int level) { verbosity_ = level; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string BuildCommandReference();
|
||||||
|
std::string BuildFewShotExamplesSection();
|
||||||
|
std::string BuildContextSection(const RomContext& context);
|
||||||
|
std::string BuildConstraintsSection();
|
||||||
|
|
||||||
|
void LoadDefaultExamples();
|
||||||
|
|
||||||
|
std::map<std::string, std::string> command_docs_; // Command name -> docs
|
||||||
|
std::vector<FewShotExample> examples_;
|
||||||
|
int verbosity_ = 1;
|
||||||
|
bool catalogue_loaded_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace cli
|
||||||
|
} // namespace yaze
|
||||||
|
|
||||||
|
#endif // YAZE_CLI_SERVICE_PROMPT_BUILDER_H_
|
||||||
@@ -48,6 +48,7 @@ add_executable(
|
|||||||
cli/handlers/agent/gui_commands.cc
|
cli/handlers/agent/gui_commands.cc
|
||||||
cli/service/ai_service.cc
|
cli/service/ai_service.cc
|
||||||
cli/service/ollama_ai_service.cc
|
cli/service/ollama_ai_service.cc
|
||||||
|
cli/service/prompt_builder.cc
|
||||||
cli/service/proposal_registry.cc
|
cli/service/proposal_registry.cc
|
||||||
cli/service/resource_catalog.cc
|
cli/service/resource_catalog.cc
|
||||||
cli/service/rom_sandbox_manager.cc
|
cli/service/rom_sandbox_manager.cc
|
||||||
|
|||||||
Reference in New Issue
Block a user