diff --git a/apps/server/src/lib/app-spec-format.ts b/apps/server/src/lib/app-spec-format.ts index 2894bbc4..0941fa4c 100644 --- a/apps/server/src/lib/app-spec-format.ts +++ b/apps/server/src/lib/app-spec-format.ts @@ -11,9 +11,13 @@ export { specOutputSchema } from '@automaker/types'; /** * Escape special XML characters + * Handles undefined/null values by converting them to empty strings */ -function escapeXml(str: string): string { - return str +function escapeXml(str: string | undefined | null): string { + if (str === undefined || str === null) { + return ''; + } + return String(str) .replace(/&/g, '&') .replace(//g, '>') diff --git a/apps/server/src/routes/app-spec/generate-spec.ts b/apps/server/src/routes/app-spec/generate-spec.ts index d79ffc5f..f519aca5 100644 --- a/apps/server/src/routes/app-spec/generate-spec.ts +++ b/apps/server/src/routes/app-spec/generate-spec.ts @@ -201,19 +201,26 @@ Your entire response should be valid JSON starting with { and ending with }. No xmlContent = responseText.substring(xmlStart, xmlEnd + ''.length); logger.info(`Extracted XML content: ${xmlContent.length} chars (from position ${xmlStart})`); } else { - // No valid XML structure found in the response text - // This happens when structured output was expected but not received, and the agent - // output conversational text instead of XML (e.g., "The project directory appears to be empty...") - // We should NOT save this conversational text as it's not a valid spec - logger.error('❌ Response does not contain valid XML structure'); - logger.error( - 'This typically happens when structured output failed and the agent produced conversational text instead of XML' - ); - throw new Error( - 'Failed to generate spec: No valid XML structure found in response. ' + - 'The response contained conversational text but no tags. ' + - 'Please try again.' - ); + // No XML found, try JSON extraction + logger.warn('⚠️ No XML tags found, attempting JSON extraction...'); + const extractedJson = extractJson(responseText, { logger }); + + if (extractedJson) { + 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( + 'This typically happens when structured output failed and the agent produced conversational text instead of structured output' + ); + throw new Error( + 'Failed to generate spec: No valid XML or JSON structure found in response. ' + + 'The response contained conversational text but no tags or valid JSON. ' + + 'Please try again.' + ); + } } }