debug-parse22.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. const fs = require('fs');
  2. const content = fs.readFileSync('temp/rich-outline-fail_57_1779015509994.txt', 'utf-8');
  3. const marker = '========== AI 原始响应 ';
  4. const markerIdx = content.indexOf(marker);
  5. const headerEndIdx = content.indexOf(' ==========', markerIdx);
  6. const aiStart = content.indexOf('\n', headerEndIdx) + 1;
  7. const aiEnd = content.indexOf('\n\n', aiStart);
  8. const aiResponse = content.substring(aiStart, aiEnd);
  9. console.log('AI response length:', aiResponse.length);
  10. // Check for the EXACT patterns my fix targets
  11. const pattern1 = '{number":';
  12. const pattern2 = '{"number":';
  13. console.log('Pattern "{number\\":":', aiResponse.includes('{number":'));
  14. console.log('Pattern "{\\"number\\":":', aiResponse.includes('{"number":'));
  15. // Let's see what character sequence is at position 1624
  16. console.log('\nExact chars at position 1624:');
  17. for (let i = 1624; i < 1635; i++) {
  18. console.log(' pos', i, ': U+' + aiResponse.charCodeAt(i).toString(16).padStart(4, '0'), JSON.stringify(aiResponse[i]));
  19. }
  20. // Check if position 1624 actually starts with { followed by "
  21. console.log('\nAt 1624, char is "{":', aiResponse[1624] === '{');
  22. console.log('At 1625, char is "\"":', aiResponse[1625] === '"');
  23. console.log('At 1626, char is "n":', aiResponse[1626] === 'n');
  24. // So it's },{\"number\":3 at positions 1620-1634
  25. // 1620: " (closing quote of mustNotRepeat array)
  26. // 1621: ] (closing bracket of mustNotRepeat array)
  27. // 1622: } (closing brace of writingInstructions)
  28. // 1623: , (comma separator)
  29. // 1624: { (OPENING NEW OBJECT)
  30. // 1625: " (opening quote of property name)
  31. // 1626: n, 1627: u, 1628: m, 1629: b, 1630: e, 1631: r (number)
  32. // 1632: " (closing quote)
  33. // 1633: : (colon)
  34. // 1634: 3 (value)
  35. // So the JSON is CORRECT! The issue must be something else.
  36. // The error message says "Expected double-quoted property name" at position 1624
  37. // But at position 1624, we have "{" which is NOT a property name!
  38. // Wait - maybe the issue is that my fix function is NOT being applied to the right string!
  39. // Let me check - the function fixMissingQuotes takes a JSON string and applies replacements
  40. // But the issue is the fix does .replace(/\{number":/g, '{"number":')
  41. // This replaces "{number": with "{\"number\":"
  42. // Let me verify this replacement works on the actual string
  43. const test1 = '{\"number":3}';
  44. const fixed1 = test1.replace(/\{number":/g, '{"number":');
  45. console.log('\nFix test:');
  46. console.log('Input:', JSON.stringify(test1));
  47. console.log('Output:', JSON.stringify(fixed1));
  48. // The actual string at 1624 is NOT {number": but just {"
  49. // Let me trace what my fix would do
  50. // My fix: .replace(/\{number":/g, '{"number":')
  51. // This replaces the LITERAL string "{number":" with '{"number":'
  52. // But in the actual JSON, the sequence is:
  53. // ...]},{"number":3,"title":"
  54. // ^-- at 1620
  55. // So at 1624 we have { followed by "number":
  56. // The string literal in my regex is: "{number":
  57. // Let's verify this is present in the JSON
  58. const idx = aiResponse.indexOf('{number":');
  59. console.log('\nIndex of "{number\\":":', idx);
  60. // Also check what's actually before position 1624
  61. console.log('\nChar before position 1624 (at 1623):', JSON.stringify(aiResponse[1623]), 'code:', aiResponse.charCodeAt(1623));
  62. // I think the issue might be that I'm looking at the WRONG error
  63. // Let me re-examine - the JSON has 39 more opening braces than closing braces
  64. // This means the JSON is TRUNCATED - some objects were never closed
  65. // And my fix function is working correctly, but the JSON is still truncated
  66. // Let me check: can I find where the JSON SHOULD end, and try to fix it there?
  67. console.log('\n=== Checking for truncation point ===');
  68. console.log('Expected closing braces:', 101 - 39); // 62 should be the target
  69. console.log('Actual closing braces:', 62);
  70. // Find where the JSON stops making sense
  71. let inString = false, escapeNext = false;
  72. let braceLevel = 0;
  73. let lastValidPos = 0;
  74. for (let i = 0; i < aiResponse.length; i++) {
  75. const ch = aiResponse[i];
  76. if (escapeNext) { escapeNext = false; continue; }
  77. if (ch === '\\') { escapeNext = true; continue; }
  78. if (ch === '"') { inString = !inString; continue; }
  79. if (inString) continue;
  80. if (ch === '{') braceLevel++;
  81. else if (ch === '}') braceLevel--;
  82. // When braceLevel goes below 0, that's where we have extra closing
  83. if (braceLevel < 0) {
  84. console.log('Brace level goes negative at position', i, '- char:', JSON.stringify(ch));
  85. break;
  86. }
  87. // Track last position where we had balanced braces at top level
  88. if (braceLevel === 0 && ch === '}') {
  89. // Try parsing
  90. try {
  91. const sub = aiResponse.substring(0, i + 1);
  92. JSON.parse(sub);
  93. lastValidPos = i + 1;
  94. } catch(e) {}
  95. }
  96. }
  97. console.log('Last valid parse position:', lastValidPos);
  98. if (lastValidPos > 0) {
  99. console.log('JSON is truncated at position', lastValidPos, 'of', aiResponse.length);
  100. console.log('We have', lastValidPos, 'valid chars but need', aiResponse.length);
  101. }