"""最终确定章节结构的节点 基于AI审查结果最终确定章节结构,并确保包含必要的标准章节。 """ import logging from typing import Dict, List, Any from ..base import BaseNode, NodeContext from ...tools.parser import DocumentChapter from .factories import ChapterFactory from .base_mixins import TocNodeBase from .category_manager import CategoryManager logger = logging.getLogger(__name__) class FinalizeChaptersNode(BaseNode, TocNodeBase): """最终确定章节结构的节点""" @property def name(self) -> str: return "finalize_chapters" @property def description(self) -> str: return "最终确定章节结构" def execute(self, state: Dict[str, Any], context: NodeContext) -> Dict[str, Any]: """执行章节最终确定""" return self.safe_execute(self._do_finalize_chapters, state, "最终确定章节结构") def _do_finalize_chapters(self, state: Dict[str, Any]) -> Dict[str, Any]: """执行实际的章节最终确定逻辑""" # 验证必需字段 if not self.validate_required_fields(state, ["preliminary_chapters"]): raise ValueError("缺少初步章节数据") # 获取调整后的章节(如果有)或原始章节 adjusted_chapters = state.get("adjusted_chapters", state["preliminary_chapters"]) # 应用最终确定逻辑(主要是确保标准章节存在) final_chapters = adjusted_chapters # 确保标准章节存在 final_chapters = self._ensure_standard_chapters(final_chapters) self._apply_saved_guidance(final_chapters, state.get("chapter_guidance_map")) self.log_step_info("finalize_chapters", f"最终生成{len(final_chapters)}个章节") return self._update_state(state, final_chapters=final_chapters, should_continue=True) # 让后续user_feedback节点决定是否继续 def _ensure_standard_chapters(self, chapters: List[DocumentChapter]) -> List[DocumentChapter]: """确保包含标准章节 Args: chapters: 当前章节列表 Returns: 包含标准章节的完整列表 """ final_chapters = chapters.copy() # 确保评标索引表存在(作为第一章) has_index = any("评标索引" in ch.title for ch in final_chapters) if not has_index: index_chapter = ChapterFactory.create_standard_chapter( "evaluation_index", "评标索引表(技术评分完全对应)", 1 ) final_chapters.insert(0, index_chapter) logger.info("添加评标索引表章节") # 可以在此添加其他必要的标准章节 # 例如:封面、目录、声明等 return final_chapters def _apply_saved_guidance(self, chapters: List[DocumentChapter], guidance_map: Dict[str, Any] | None) -> None: if not guidance_map: return for chapter in chapters: category_key = CategoryManager.infer_category_for_chapter(chapter) guidance = guidance_map.get(category_key) if guidance: chapter.guidance = guidance if chapter.children: self._apply_saved_guidance(chapter.children, guidance_map)