eat: make Gemma 4 the default model, enable thinking mode

This commit is contained in:
Aaron Po
2026-04-10 21:43:18 -04:00
parent 61d5077a95
commit 902bda6eb9
16 changed files with 263 additions and 558 deletions

View File

@@ -6,15 +6,65 @@
#include <spdlog/spdlog.h>
#include <array>
#include <stdexcept>
#include <string>
#include "data_generation/llama_generator.h"
#include "data_generation/llama_generator_helpers.h"
BreweryResult LlamaGenerator::GenerateBrewery(
const std::string& city_name, const std::string& country_name,
const std::string& region_context) {
namespace {
auto ExtractFinalJsonPayload(std::string raw_response) -> std::string {
auto trim = [](std::string_view text) -> std::string_view {
const std::size_t first = text.find_first_not_of(" \t\n\r");
if (first == std::string_view::npos) {
return {};
}
const std::size_t last = text.find_last_not_of(" \t\n\r");
return text.substr(first, last - first + 1);
};
static const std::array<std::string_view, 4> separator_tokens = {
"<|turn|>", "<turn|>", "<channel|>", "<|channel|>"};
std::size_t separator_pos = std::string::npos;
std::size_t separator_length = 0;
for (const std::string_view token : separator_tokens) {
const std::size_t candidate_pos = raw_response.rfind(token);
if (candidate_pos != std::string::npos &&
(separator_pos == std::string::npos ||
candidate_pos > separator_pos)) {
separator_pos = candidate_pos;
separator_length = token.size();
}
}
if (separator_pos != std::string::npos) {
raw_response.erase(0, separator_pos + separator_length);
}
const std::string_view trimmed = trim(raw_response);
const std::size_t first_brace = trimmed.find('{');
if (first_brace == std::string_view::npos) {
return std::string(trimmed);
}
const std::size_t last_brace = trimmed.find_last_of('}');
if (last_brace == std::string_view::npos || last_brace < first_brace) {
return std::string(trimmed.substr(first_brace));
}
return std::string(
trimmed.substr(first_brace, last_brace - first_brace + 1));
}
} // namespace
auto LlamaGenerator::GenerateBrewery(const BreweryLocation& location,
const std::string& region_context)
-> BreweryResult {
/**
* Preprocess and truncate region context to manageable size
*/
@@ -24,10 +74,9 @@ BreweryResult LlamaGenerator::GenerateBrewery(
/**
* Load brewery system prompt from file
* Falls back to minimal inline prompt if file not found
* Default path: prompts/brewery_system_prompt_expanded.txt
*/
const std::string system_prompt =
LoadBrewerySystemPrompt("prompts/brewery_system_prompt_expanded.txt");
LoadBrewerySystemPrompt("prompts/system.md");
/**
* User prompt: provides geographic context to guide generation towards
@@ -35,21 +84,28 @@ BreweryResult LlamaGenerator::GenerateBrewery(
*/
std::string prompt =
"Write a brewery name and place-specific long description for a craft "
"brewery in " +
city_name +
(country_name.empty() ? std::string("")
: std::string(", ") + country_name) +
(safe_region_context.empty()
? std::string(".")
: std::string(". Regional context: ") + safe_region_context);
"brewery in ";
prompt.append(location.city_name);
if (!location.country_name.empty()) {
prompt.append(", ");
prompt.append(location.country_name);
}
if (safe_region_context.empty()) {
prompt.append(".");
} else {
prompt.append(". Regional context: ");
prompt.append(safe_region_context);
}
/**
* Store location context for retry prompts (without repeating full context)
*/
const std::string retry_location =
"Location: " + city_name +
(country_name.empty() ? std::string("")
: std::string(", ") + country_name);
std::string retry_location = "Location: ";
retry_location.append(location.city_name);
if (!location.country_name.empty()) {
retry_location.append(", ");
retry_location.append(location.country_name);
}
/**
* RETRY LOOP with validation and error correction
@@ -72,8 +128,9 @@ BreweryResult LlamaGenerator::GenerateBrewery(
std::string name;
std::string description;
const std::string json_only = ExtractFinalJsonPayload(raw);
const std::string validation_error =
ValidateBreweryJsonPublic(raw, name, description);
ValidateBreweryJsonPublic(json_only, name, description);
if (validation_error.empty()) {
// Success: return parsed brewery data
return {std::move(name), std::move(description)};
@@ -92,9 +149,9 @@ BreweryResult LlamaGenerator::GenerateBrewery(
"Your previous response was invalid. Error: " + validation_error +
"\nReturn ONLY valid JSON with this exact schema: "
"{\"name\": \"string\", \"description\": \"string\"}."
"\nDo not include markdown, comments, or extra keys."
"\n\n" +
retry_location;
"\nDo not include markdown, comments, or extra keys.";
prompt += "\n\n";
prompt += retry_location;
}
// All retry attempts exhausted: log failure and throw exception