fix: salvage backstory from truncated JSON, request compact output

Model sometimes returns pretty-printed JSON with newlines/indentation,
wasting tokens and causing truncation. Now requests compact single-line
JSON. When JSON is truncated, regex-extracts the backstory field rather
than setting raw JSON as the backstory text.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
root
2026-03-10 18:49:06 +00:00
parent 2b5bf86b0f
commit dc6dd946a2
2 changed files with 10 additions and 2 deletions

View File

@@ -120,7 +120,15 @@ export async function generateBackstoryAndDesires(
try {
parsed = JSON.parse(result);
} catch {
// JSON parse failed — use raw string as backstory fallback
// Try to salvage truncated JSON — extract backstory field even if desires are cut off
const backstoryMatch = result.match(/"backstory"\s*:\s*"((?:[^"\\]|\\.)*)"/);
if (backstoryMatch) {
logService?.log('warning', 'LLM', `JSON truncated for backstory (entity ${entityId}), salvaged backstory field`);
logLlmDebug({ templateName: 'backstoryAndDesires', stage: 'parse_salvaged', response: result });
world.addComponent<string>(entityId, 'backstory', backstoryMatch[1]);
return;
}
// Truly unparseable — use raw string as backstory fallback
logService?.log('warning', 'LLM', `JSON parse failed for backstory (entity ${entityId}), using raw string`);
logLlmDebug({ templateName: 'backstoryAndDesires', stage: 'parse_failed', response: result });
world.addComponent<string>(entityId, 'backstory', result);

View File

@@ -75,7 +75,7 @@ export const templates: Record<string, PromptTemplate> = {
'The backstory should reflect their personality without referencing professions or institutions that do not exist. ' +
'Desires should be grounded in what is achievable or aspirational given the current world state.\n\n' +
'Be concise. Keep backstory under 2 sentences. Keep desire descriptions short (under 10 words).\n\n' +
'Respond ONLY with a valid JSON object. No explanation, no markdown, just JSON.',
'Respond ONLY with compact single-line JSON. No newlines, no indentation, no markdown.',
userPrompt:
'New settler: {{npcName}}\n' +
'Stats (each ranges 3-18, 10 is average): {{stats}}\n\n' +