| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- 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);
- // The error is at position 1624, char "{" code 123
- // Error: Expected double-quoted property name
- // This means when the parser hits {, it expected "propertyName": first
- // This can happen if:
- // 1. We're at the start of a new object but the previous object wasn't properly closed
- // 2. There's a structural error that makes the parser think we're in the wrong place
- // Let me trace the brace/bracket depth and check where it goes negative
- let inString = false;
- let escapeNext = false;
- let braceLevel = 0; // { }
- let bracketLevel = 0; // [ ]
- let pos = 0;
- let errorPos = 1624;
- for (let i = 0; i <= errorPos; 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++;
- if (i === errorPos) {
- console.log('At error pos, opening brace, levels: brace=', braceLevel, 'bracket=', bracketLevel);
- }
- } else if (ch === '}') {
- braceLevel--;
- if (i === errorPos) {
- console.log('At error pos, closing brace, levels: brace=', braceLevel, 'bracket=', bracketLevel);
- }
- } else if (ch === '[') {
- bracketLevel++;
- if (i === errorPos) {
- console.log('At error pos, opening bracket, levels: brace=', braceLevel, 'bracket=', bracketLevel);
- }
- } else if (ch === ']') {
- bracketLevel--;
- if (i === errorPos) {
- console.log('At error pos, closing bracket, levels: brace=', braceLevel, 'bracket=', bracketLevel);
- }
- }
- // Check what levels are at errorPos-1 (the char before the error)
- if (i === errorPos - 1) {
- console.log('Before error pos (at ' + i + '):', JSON.stringify(ch), 'levels: brace=', braceLevel, 'bracket=', bracketLevel);
- }
- }
- console.log('\nAt error position 1624 itself, before processing it:');
- // Calculate levels BEFORE processing char at 1624
- let braceBefore = 0, bracketBefore = 0;
- inString = false;
- escapeNext = false;
- for (let i = 0; i < 1624; 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 === '{') braceBefore++;
- else if (ch === '}') braceBefore--;
- else if (ch === '[') bracketBefore++;
- else if (ch === ']') bracketBefore--;
- }
- console.log('Before processing char at 1624: braceLevel=' + braceBefore + ' bracketLevel=' + bracketBefore);
- console.log('Char at 1624 is:', JSON.stringify(aiResponse[1624]));
- // The char at 1624 is "{" - so after processing it, braceLevel would be braceBefore+1
- console.log('If we process {, braceLevel would become:', braceBefore + 1);
- // But the ERROR says at position 1624 we saw { and expected a property name
- // This means braceLevel must have been 0 BEFORE processing the {, meaning
- // we're trying to open a new object at the top level, which is fine IF we
- // just had a comma
- // Wait - let me check what's BEFORE the { at 1624
- console.log('\n=== Context before the { at 1624 ===');
- console.log(JSON.stringify(aiResponse.substring(1580, 1640)));
- // The substring shows: ...],\"mustNotRepeat\":[...],{\"number\":3,...
- // So it's: ]},{"number":3
- // That ] closes an array, } closes an object, , separates, { starts new object
- // This is valid if we're adding to a chapters array!
- // Let me try a different approach - parse the JSON and see where it fails
- // by trying to parse chunks
- console.log('\n=== Trying incremental parse ===');
- let lastGoodPos = 0;
- inString = false;
- escapeNext = false;
- braceLevel = 0;
- bracketLevel = 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--;
- else if (ch === '[') bracketLevel++;
- else if (ch === ']') bracketLevel--;
- // Try parsing up to this point
- if ((ch === '}' || ch === ',') && braceLevel === 0 && bracketLevel === 0) {
- try {
- JSON.parse(aiResponse.substring(0, i + 1));
- lastGoodPos = i + 1;
- } catch(e) {
- if (i > 1600 && i < 1700) {
- console.log('Parse failed at', i, 'char', JSON.stringify(ch), 'error:', e.message.substring(0, 60));
- }
- }
- }
- }
- console.log('Last good parse position:', lastGoodPos);
- console.log('Context around last good:', JSON.stringify(aiResponse.substring(lastGoodPos - 20, lastGoodPos + 40)));
|