debug-parse24.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. const fs = require('fs');
  2. const content = fs.readFileSync('temp/rich-outline-fail_57_1779017412608.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 if the new fail file has a different error
  11. const pos = parseInt(content.match(/position (\d+)/)?.[1] || '0');
  12. console.log('Error position in file:', pos);
  13. // Check for truncation
  14. let openBraces = 0, closeBraces = 0;
  15. let inString = false, escapeNext = false;
  16. for (let i = 0; i < aiResponse.length; i++) {
  17. const ch = aiResponse[i];
  18. if (escapeNext) { escapeNext = false; continue; }
  19. if (ch === '\\') { escapeNext = true; continue; }
  20. if (ch === '"') { inString = !inString; continue; }
  21. if (inString) continue;
  22. if (ch === '{') openBraces++;
  23. else if (ch === '}') closeBraces++;
  24. }
  25. console.log('Open braces:', openBraces, 'Close:', closeBraces, 'Diff:', openBraces - closeBraces);
  26. console.log('Ends with }:', aiResponse.trim().endsWith('}'));
  27. try {
  28. JSON.parse(aiResponse);
  29. console.log('Raw parse: SUCCESS');
  30. } catch(e) {
  31. console.log('Raw parse FAILED:', e.message.substring(0, 100));
  32. // Check position
  33. const errorPos = parseInt(e.message.match(/position (\d+)/)?.[1] || '0');
  34. if (errorPos > 0 && errorPos < aiResponse.length) {
  35. console.log('Context around error:');
  36. console.log(JSON.stringify(aiResponse.substring(Math.max(0, errorPos-50), errorPos+50)));
  37. }
  38. }
  39. // Try with fixMissingQuotes
  40. function fixMissingQuotes(jsonStr) {
  41. return jsonStr
  42. .replace(/\{number":/g, '{"number":')
  43. .replace(/\{title":/g, '{"title":')
  44. .replace(/\{summary":/g, '{"summary":')
  45. .replace(/\{opening":/g, '{"opening":')
  46. .replace(/\{structure":/g, '{"structure":')
  47. .replace(/\{mustCover":/g, '{"mustCover":')
  48. .replace(/\{mustNotRepeat":/g, '{"mustNotRepeat":')
  49. .replace(/\{toneAdjustment":/g, '{"toneAdjustment":')
  50. .replace(/\{keyTakeaway":/g, '{"keyTakeaway":')
  51. .replace(/\{keyPoints":/g, '{"keyPoints":')
  52. .replace(/\{estimatedWords":/g, '{"estimatedWords":')
  53. .replace(/\{writingInstructions":/g, '{"writingInstructions":');
  54. }
  55. const fixed = fixMissingQuotes(aiResponse);
  56. try {
  57. JSON.parse(fixed);
  58. console.log('Fixed parse: SUCCESS');
  59. } catch(e) {
  60. console.log('Fixed parse FAILED:', e.message.substring(0, 100));
  61. }
  62. // Check what strategy 9 would extract
  63. console.log('\n=== Testing strategy 9 extraction ===');
  64. const chaptersArrayStart = aiResponse.indexOf('"chapters":[');
  65. if (chaptersArrayStart !== -1) {
  66. let bracketDepth = 0;
  67. let inString = false;
  68. let escapeNext = false;
  69. let arrayEnd = -1;
  70. for (let i = chaptersArrayStart + 12; i < aiResponse.length; i++) {
  71. const ch = aiResponse[i];
  72. if (escapeNext) { escapeNext = false; continue; }
  73. if (ch === '\\') { escapeNext = true; continue; }
  74. if (ch === '"') { inString = !inString; continue; }
  75. if (inString) continue;
  76. if (ch === '[') bracketDepth++;
  77. else if (ch === ']') { bracketDepth--; if (bracketDepth === 0) { arrayEnd = i; break; } }
  78. }
  79. console.log('Chapters array ends at:', arrayEnd);
  80. const arrayContent = aiResponse.substring(chaptersArrayStart + 12, arrayEnd);
  81. const fixedContent = fixMissingQuotes(arrayContent);
  82. try {
  83. const chapters = JSON.parse('[' + fixedContent + ']');
  84. console.log('Parsed chapters array: SUCCESS, count:', chapters.length);
  85. } catch(e) {
  86. console.log('Parsed chapters array: FAILED -', e.message.substring(0, 80));
  87. // Try one by one
  88. const chapterMatches = fixedContent.match(/\{[^}]+\}/g) || [];
  89. console.log('Found', chapterMatches.length, 'chapter objects by regex');
  90. let validChapters = 0;
  91. for (const chStr of chapterMatches) {
  92. try {
  93. JSON.parse(chStr);
  94. validChapters++;
  95. } catch(e) {}
  96. }
  97. console.log('Valid chapter objects:', validChapters);
  98. }
  99. }