| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- 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('Length:', aiResponse.length);
- // Goal: Find the chapters that are COMPLETE (both opening and closing braces)
- // by finding the last position where we have a valid chapter object
- // Strategy: Find all "chapters": [ patterns, then find where each chapter ends
- // A chapter ends when we see "}," or "]," patterns that close the chapter object
- // Actually, let's try a different approach: find the last complete "number":X in a chapters array
- // and work backwards to find the full chapter
- // First, find where chapters array starts
- const chaptersStart = aiResponse.indexOf('"chapters":[');
- console.log('Chapters array starts at:', chaptersStart);
- if (chaptersStart === -1) {
- console.log('No chapters array found');
- process.exit(1);
- }
- // Try to find where the JSON becomes invalid - that's our truncation point
- // Then extract all chapters before that
- let lastGoodPos = chaptersStart;
- let braceLevel = 0;
- let inString = false;
- let escapeNext = false;
- for (let i = chaptersStart; 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--;
- else if (ch === '[') braceLevel++;
- else if (ch === ']') braceLevel--;
- if (braceLevel < 0) {
- console.log('JSON goes negative at position', i, '- char', JSON.stringify(ch));
- break;
- }
- // Try to parse up to this point
- const sub = '{"outline":' + aiResponse.substring(chaptersStart, i + 1) + '}';
- try {
- JSON.parse(sub);
- lastGoodPos = i + 1;
- } catch(e) {
- // If it fails because braces are unbalanced, that's ok - we might be mid-chapter
- if (!e.message.includes('Unexpected end')) {
- // Some other error
- }
- }
- }
- console.log('Last position where prefix might be valid:', lastGoodPos);
- console.log('Prefix length:', lastGoodPos - chaptersStart);
- // Try to extract the complete chapters from the prefix
- const prefix = '{"outline":{"chapters":' + aiResponse.substring(chaptersStart + 13, lastGoodPos) + '}}';
- console.log('\nTrying to parse prefix as complete outline...');
- try {
- const data = JSON.parse(prefix);
- console.log('SUCCESS! Chapters:', data.outline?.chapters?.length);
- if (data.outline?.chapters?.length > 0) {
- console.log('First chapter:', data.outline.chapters[0].title);
- console.log('Last chapter:', data.outline.chapters[data.outline.chapters.length - 1].title);
- }
- } catch(e) {
- console.log('FAILED:', e.message.substring(0, 100));
- // Try a more aggressive approach - just extract complete chapter objects
- console.log('\n=== Trying chapter-by-chapter extraction ===');
- // Find all occurrences of "number":N where N is a number
- const chapterNumRegex = /"number":(\d+)/g;
- let match;
- let chapters = [];
- let lastEnd = chaptersStart + 13; // After "chapters":[
- while ((match = chapterNumRegex.exec(aiResponse)) !== null) {
- const num = parseInt(match[1]);
- const startPos = match.index;
- // Find the end of this chapter - look for }], or }},{ patterns
- let endSearchStart = startPos + match[0].length;
- // Find the next "number": pattern or end of chapters array
- const nextNumMatch = chapterNumRegex.exec(aiResponse.substring(endSearchStart));
- const endPos = nextNumMatch ? endSearchStart + nextNumMatch.index : aiResponse.lastIndexOf(']}', aiResponse.length);
- const chapterJson = '{"number":' + num + aiResponse.substring(startPos + 9, endPos);
- try {
- const chapter = JSON.parse(chapterJson);
- if (chapter.title && chapter.summary) {
- chapters.push(chapter);
- console.log('Found chapter', num + ':', chapter.title, 'length:', chapterJson.length);
- }
- } catch(e) {
- console.log('Chapter', num, 'parse failed:', e.message.substring(0, 50));
- }
- }
- console.log('\nTotal complete chapters found:', chapters.length);
- }
|