/m; let cleanedOutput = rawLLMOutput; const match = rawLLMOutput.match(jsonRegex); if (match && match[1]) { cleanedOutput = match[1]; } else { // More robust repair could involve a dedicated library // For demonstration, a basic attempt to find first '{' and last '}' const firstBracket = cleanedOutput.indexOf('{'); const lastBracket = cleanedOutput.lastIndexOf('}'); if (firstBracket !== -1 && lastBracket !== -1 && lastBracket > firstBracket) { cleanedOutput = cleanedOutput.substring(firstBracket, lastBracket + 1); } else { const firstArrayBracket = cleanedOutput.indexOf('['); const lastArrayBracket = cleanedOutput.lastIndexOf(']'); if (firstArrayBracket !== -1 && lastArrayBracket !== -1 && lastArrayBracket > firstArrayBracket) { cleanedOutput = cleanedOutput.substring(firstArrayBracket, lastArrayBracket + 1); } } } parsedJson = JSON.parse(cleanedOutput); console.warn('JSON repaired successfully.'); } catch (repairError) { error = `Failed to parse JSON even after repair: ${e.message} and ${repairError}`; return { data: null, errors: error }; } } // Validate against the schema const validationResult = schema.safeParse(parsedJson); if (validationResult.success) { return { data: validationResult.data, errors: null }; } else { // Handle partial data recovery for arrays if (schema instanceof z.ZodArray && Array.isArray(parsedJson)) { const itemSchema = (schema as z.ZodArray).element; const partialData: any[] = []; const itemErrors: z.ZodError[] = []; parsedJson.forEach((item, index) => { const itemValidationResult = itemSchema.safeParse(item); if (itemValidationResult.success) { partialData.push(itemValidationResult.data); } else { itemErrors.push(new z.ZodError([ { ...itemValidationResult.error.errors[0], path: [`${index}`].concat(itemValidationResult.error.errors[0].path) } ])); } }); if (partialData.length > 0) { console.warn(`Partial data extracted successfully: ${partialData.length} items out of ${parsedJson.length}.`); return { data: parsedJson, errors: new z.ZodError(itemErrors.flatMap(e => e.errors)), partialData: partialData }; } } console.error('Schema validation failed:', validationResult.error); return { data: null, errors: validationResult.error }; } } // Example usage: const malformedJsonOutput = ` This is some introductory text. \`\`\`json [ {"id": "A1", "value": 100}, {"id": "B2", "value": "invalid"}, // Malformed value {"id": "C3", "value": 300}, {"id": "D4", "value": -50} // Invalid positive number ] \`\`\` Some trailing text. `; const schemaForArray = z.array(itemSchema); const result = parseAndValidateWithRecovery(malformedJsonOutput, schemaForArray); console.log('\nResult:', result); /* Expected output will show errors for B2 and D4, but partialData will contain A1 and C3 */