Merge pull request #514 from Seonfx/fix/510-spec-generation-json-fallback

fix: add JSON fallback for spec generation with custom API endpoints
This commit is contained in:
Shirone
2026-01-16 19:01:47 +00:00
committed by GitHub
2 changed files with 32 additions and 14 deletions

View File

@@ -11,8 +11,12 @@ export { specOutputSchema } from '@automaker/types';
/** /**
* Escape special XML characters * Escape special XML characters
* Handles undefined/null values by converting them to empty strings
*/ */
function escapeXml(str: string): string { function escapeXml(str: string | undefined | null): string {
if (str == null) {
return '';
}
return str return str
.replace(/&/g, '&') .replace(/&/g, '&')
.replace(/</g, '&lt;') .replace(/</g, '&lt;')

View File

@@ -201,21 +201,35 @@ Your entire response should be valid JSON starting with { and ending with }. No
xmlContent = responseText.substring(xmlStart, xmlEnd + '</project_specification>'.length); xmlContent = responseText.substring(xmlStart, xmlEnd + '</project_specification>'.length);
logger.info(`Extracted XML content: ${xmlContent.length} chars (from position ${xmlStart})`); logger.info(`Extracted XML content: ${xmlContent.length} chars (from position ${xmlStart})`);
} else { } else {
// No valid XML structure found in the response text // No XML found, try JSON extraction
// This happens when structured output was expected but not received, and the agent logger.warn('⚠️ No XML tags found, attempting JSON extraction...');
// output conversational text instead of XML (e.g., "The project directory appears to be empty...") const extractedJson = extractJson<SpecOutput>(responseText, { logger });
// We should NOT save this conversational text as it's not a valid spec
logger.error('❌ Response does not contain valid <project_specification> XML structure'); if (
extractedJson &&
typeof extractedJson.project_name === 'string' &&
typeof extractedJson.overview === 'string' &&
Array.isArray(extractedJson.technology_stack) &&
Array.isArray(extractedJson.core_capabilities) &&
Array.isArray(extractedJson.implemented_features)
) {
logger.info('✅ Successfully extracted JSON from response text');
xmlContent = specToXml(extractedJson);
logger.info(`✅ Converted extracted JSON to XML: ${xmlContent.length} chars`);
} else {
// Neither XML nor valid JSON found
logger.error('❌ Response does not contain valid XML or JSON structure');
logger.error( logger.error(
'This typically happens when structured output failed and the agent produced conversational text instead of XML' 'This typically happens when structured output failed and the agent produced conversational text instead of structured output'
); );
throw new Error( throw new Error(
'Failed to generate spec: No valid XML structure found in response. ' + 'Failed to generate spec: No valid XML or JSON structure found in response. ' +
'The response contained conversational text but no <project_specification> tags. ' + 'The response contained conversational text but no <project_specification> tags or valid JSON. ' +
'Please try again.' 'Please try again.'
); );
} }
} }
}
// Save spec to .automaker directory // Save spec to .automaker directory
await ensureAutomakerDir(projectPath); await ensureAutomakerDir(projectPath);