const fs = require('fs'); const file = 'src/modules/book-generator/langgraph-generator.ts'; let content = fs.readFileSync(file, 'utf8'); // 找到 parseSubsections 函数并完全替换 const startMarker = 'function parseSubsections(jsonStr: string): { subsections: any[] } | null {'; const endMarker = '// ============ LangGraph 节点 ============'; const startIndex = content.indexOf(startMarker); const endIndex = content.indexOf(endMarker); if (startIndex === -1 || endIndex === -1) { console.error('未找到函数标记'); process.exit(1); } const newFunction = `function parseSubsections(jsonStr: string): { subsections: any[] } | null { if (!jsonStr || typeof jsonStr !== 'string') { console.error('[SubsectionParser] 输入为空或非字符串'); return null; } try { let data: any; let cleanedStr = jsonStr.trim(); // 移除 ... 标签 const thinkMatch = cleanedStr.match(/([\\s\\S]*)/); if (thinkMatch) { cleanedStr = thinkMatch[1].trim(); } // 移除 markdown 代码块标记 cleanedStr = cleanedStr.replace(/^\`\`\`json\\s*/gi, '').replace(/^\`\`\`\\s*/gm, '').replace(/\`\`\`\\s*$/gm, '').trim(); // 找到第一个 { 和最后一个 } const firstBrace = cleanedStr.indexOf('{'); const lastBrace = cleanedStr.lastIndexOf('}'); if (firstBrace === -1 || lastBrace === -1) { console.error('[SubsectionParser] 未找到 JSON 对象'); return null; } const jsonStr_extracted = cleanedStr.substring(firstBrace, lastBrace + 1); try { data = JSON.parse(jsonStr_extracted); } catch (parseErr) { console.error('[SubsectionParser] JSON 解析失败:', parseErr); console.error('[SubsectionParser] 提取的JSON前100字符:', jsonStr_extracted.substring(0, 100)); return null; } if (!data || typeof data !== 'object') { console.error('[SubsectionParser] 解析结果非对象'); return null; } // 兼容:如果顶层就是数组 if (Array.isArray(data)) { data = { subsections: data }; } // 兼容多种字段名:subsections, Subsections, subsection_list 等 let subsectionsArray = data.subsections || data.Subsections || data.subsection_list || data.section_subsections; if (!Array.isArray(subsectionsArray)) { console.error('[SubsectionParser] subsections 字段缺失或非数组'); return null; } return { subsections: subsectionsArray.map((s: any, i: number) => ({ number: s.number || i + 1, title: s.title || \`第\${i + 1}小节\`, summary: typeof s.summary === 'string' ? s.summary : '', keyPoints: Array.isArray(s.keyPoints) ? s.keyPoints : [], estimatedWords: typeof s.estimatedWords === 'number' ? s.estimatedWords : 500, })), }; } catch (err) { console.error('[SubsectionParser] 未知错误:', err); return null; } } `; content = content.substring(0, startIndex) + newFunction + content.substring(endIndex); fs.writeFileSync(file, content, 'utf8'); console.log('✅ parseSubsections 函数已重写');