const fs = require('fs'); const content = fs.readFileSync('temp/rich-outline-fail_57_1779015509994.txt', 'utf-8'); const marker = '========== AI 原始响应 '; const markerIdx = content.indexOf(marker); const headerEndIdx = content.indexOf(' ==========', markerIdx); const aiStart = content.indexOf('\n', headerEndIdx) + 1; const aiEnd = content.indexOf('\n\n', aiStart); const aiResponse = content.substring(aiStart, aiEnd); console.log('AI response length:', aiResponse.length); // Let's try isolating the problematic section // Around position 1624 we have: ...]},{"number":3,"title":"干枯的笔",... // Try to create a minimal JSON with just the section around the error const before = '{"chapters":[{"writingInstructions":{"mustNotRepeat":["a","b"]},'; const after = '}]}'; const middle = aiResponse.substring(1610, 1700); const testJson = before + middle + after; console.log('\n=== Test: surround error area with valid JSON ==='); console.log('Test JSON length:', testJson.length); try { const data = JSON.parse(testJson); console.log('SUCCESS'); } catch(e) { console.log('FAILED:', e.message.substring(0, 100)); } // Now let's check: maybe the issue is with the FIRST character after the error position // Let me see what happens if we parse from 1620 to 1650 console.log('\n=== Parse tiny snippet ==='); const snippet = aiResponse.substring(1600, 1650); console.log('Snippet:', JSON.stringify(snippet)); try { JSON.parse(snippet); console.log('SUCCESS'); } catch(e) { console.log('FAILED:', e.message); } // Try parsing the JSON up to position 1620 console.log('\n=== Parse up to position 1620 ==='); const prefix = aiResponse.substring(0, 1620) + '"]}]}]}'; try { JSON.parse(prefix); console.log('SUCCESS'); } catch(e) { console.log('FAILED:', e.message.substring(0, 100)); } // Most importantly - let's check if the ACTUAL issue is that the AI returned a malformed // JSON that's missing some key structure. Let me check the mainTheme and chapters structure console.log('\n=== Check main structure ==='); const mainThemeMatch = aiResponse.match(/"mainTheme"\s*:\s*"([^"]+)"/); console.log('mainTheme found:', mainThemeMatch ? 'yes, length ' + mainThemeMatch[1].length : 'no'); const chaptersArrayMatch = aiResponse.match(/"chapters"\s*:\s*\[/); console.log('chapters array found:', chaptersArrayMatch ? 'yes' : 'no'); const mainThemeValue = mainThemeMatch ? mainThemeMatch[1] : ''; console.log('\nmainTheme value first 100 chars:', JSON.stringify(mainThemeValue.substring(0, 100))); // Let me try to count braces and brackets in the entire string to find imbalance console.log('\n=== Brace/Bracket counting ==='); let braceLevel = 0; let bracketLevel = 0; let inString = false; let escapeNext = false; let minBraceLevel = 0; let minBracketLevel = 0; for (let i = 0; i < aiResponse.length; i++) { const ch = aiResponse[i]; if (escapeNext) { escapeNext = false; continue; } if (ch === '\\') { escapeNext = true; continue; } if (ch === '"') { inString = !inString; continue; } if (inString) continue; if (ch === '{') { braceLevel++; } else if (ch === '}') { braceLevel--; if (braceLevel < minBraceLevel) minBraceLevel = braceLevel; } else if (ch === '[') { bracketLevel++; } else if (ch === ']') { bracketLevel--; if (bracketLevel < minBracketLevel) minBracketLevel = bracketLevel; } } console.log('Final brace level:', braceLevel, '(should be 0)'); console.log('Final bracket level:', bracketLevel, '(should be 0)'); console.log('Minimum brace level reached:', minBraceLevel); console.log('Minimum bracket level reached:', minBracketLevel); if (braceLevel !== 0 || bracketLevel !== 0) { console.log('JSON is UNBALANCED - this is the root cause!'); } else { console.log('JSON is balanced - the issue must be somewhere specific'); }