144 lines
4.6 KiB
Python
144 lines
4.6 KiB
Python
from bidmaster.nodes.base import NodeContext
|
|
from bidmaster.nodes.toc import generate_sub_chapters as gen_module
|
|
from bidmaster.nodes.toc.generate_sub_chapters import GenerateSubChaptersNode
|
|
from bidmaster.nodes.toc.user_feedback import UserFeedbackNode
|
|
from bidmaster.tools.parser import DocumentChapter, ScoringCriteria, TechnicalCategory
|
|
from bidmaster.utils.document_context import DocumentContext, DocumentContextMatch
|
|
|
|
|
|
def test_generate_sub_chapters_uses_context(monkeypatch):
|
|
captured = {}
|
|
|
|
def fake_generate(criteria_list, parent_chapter, context_snippets=None, tech_consistency_prompt=None):
|
|
captured["context"] = context_snippets
|
|
captured["consistency"] = tech_consistency_prompt
|
|
return [{"title": "示例小节", "level": 2, "score": 5, "children": []}]
|
|
|
|
class DummySearcher:
|
|
def __init__(self, *args, **kwargs):
|
|
pass
|
|
|
|
def search(self, query, top_k=None):
|
|
return [
|
|
DocumentContextMatch(
|
|
text="系统采用云边协同架构,强调稳定性。",
|
|
section="项目概述",
|
|
score=0.95,
|
|
source_type="paragraph",
|
|
metadata={},
|
|
)
|
|
]
|
|
|
|
monkeypatch.setattr(gen_module, "DocumentContextSearcher", DummySearcher)
|
|
monkeypatch.setattr(gen_module.LLMHelper, "generate_sub_chapters_ai", staticmethod(fake_generate))
|
|
|
|
chapter = DocumentChapter(
|
|
id="chapter_01_technical_solution",
|
|
title="技术方案",
|
|
level=1,
|
|
score=30,
|
|
)
|
|
criteria = [
|
|
ScoringCriteria(
|
|
item_name="系统架构先进性",
|
|
max_score=10,
|
|
description="阐述云边端协同",
|
|
category=TechnicalCategory.TECHNICAL_SOLUTION,
|
|
chapter_id="chapter_01_technical_solution",
|
|
original_index=0,
|
|
)
|
|
]
|
|
|
|
state = {
|
|
"preliminary_chapters": [chapter],
|
|
"technical_criteria": criteria,
|
|
"document_context": DocumentContext("demo.docx", "test-model", []),
|
|
"tech_consistency_prompt": "统一术语:云边端协同/边缘节点/终端设备",
|
|
}
|
|
|
|
node = GenerateSubChaptersNode()
|
|
result = node.execute(state, NodeContext())
|
|
|
|
assert result["preliminary_chapters"][0].children
|
|
assert captured["context"] and "项目概述" in captured["context"][0]
|
|
assert "统一术语" in (captured["consistency"] or "")
|
|
|
|
|
|
def test_user_feedback_auto_triggers_optimization():
|
|
chapters = [
|
|
DocumentChapter(
|
|
id="chapter_01",
|
|
title="技术方案",
|
|
level=1,
|
|
score=30,
|
|
)
|
|
]
|
|
|
|
state = {
|
|
"final_chapters": chapters,
|
|
"structure_review": {
|
|
"suggestions": [
|
|
{"description": "补充智慧运维章节", "priority": "high", "type": "add"},
|
|
{"description": "可选优化", "priority": "low", "type": "modify"},
|
|
]
|
|
},
|
|
"auto_mode": True,
|
|
"auto_toc_max_rounds": 2,
|
|
"auto_optimization_rounds": 0,
|
|
}
|
|
|
|
node = UserFeedbackNode()
|
|
result = node.execute(state, NodeContext())
|
|
|
|
assert result["needs_optimization"] is True
|
|
assert "补充" in result["user_feedback"]
|
|
assert result["auto_optimization_rounds"] == 1
|
|
assert result["pending_suggestions"] == []
|
|
|
|
|
|
def test_user_feedback_auto_skips_when_no_priority():
|
|
chapters = [
|
|
DocumentChapter(
|
|
id="chapter_02",
|
|
title="实施计划",
|
|
level=1,
|
|
score=20,
|
|
)
|
|
]
|
|
|
|
state = {
|
|
"final_chapters": chapters,
|
|
"structure_review": {"suggestions": [{"description": "微调描述", "priority": "low", "type": "modify"}]},
|
|
"auto_mode": True,
|
|
"auto_toc_max_rounds": 1,
|
|
}
|
|
|
|
node = UserFeedbackNode()
|
|
result = node.execute(state, NodeContext())
|
|
|
|
assert result["needs_optimization"] is False
|
|
assert result["user_feedback"] == ""
|
|
|
|
|
|
def test_user_feedback_auto_respects_round_limit():
|
|
chapters = [
|
|
DocumentChapter(id="chapter_03", title="服务方案", level=1, score=10)
|
|
]
|
|
|
|
state = {
|
|
"final_chapters": chapters,
|
|
"structure_review": {
|
|
"suggestions": [{"description": "增加服务考核", "priority": "high", "type": "add"}]
|
|
},
|
|
"auto_mode": True,
|
|
"auto_toc_max_rounds": 1,
|
|
"auto_optimization_rounds": 1,
|
|
"pending_suggestions": [{"description": "增加服务考核", "priority": "high", "type": "add"}],
|
|
}
|
|
|
|
node = UserFeedbackNode()
|
|
result = node.execute(state, NodeContext())
|
|
|
|
assert result["needs_optimization"] is False
|
|
assert result["pending_suggestions"] == []
|