- Writer: 表格表头行/Table Grid 边框、列表 List Bullet/Number 样式、行内字符格式不再塌缩(外视 #6 反转) - Writer: 打通章间引用(WriterState 摘要 → 后章 prompt prior_summaries) - Writer: 删除 _chunk_source 死代码,章节数据经 DataGate 控 token 预算 - Writer: 章节结果落盘快照,命中即跳过 LLM(录制重拍可续跑,损坏快照自动忽略) - Parser: 按 body 顺序遍历正文+单元格(含嵌套表、合并单元格去重),修复表格内锚点漏检导致的静默丢章 - Parser/服务层: .xls 显式拒绝(可操作提示),上传即校验扩展名,rules 对齐 docx-only - 测试: 全量 680 通过,覆盖率 99.37%(红线 99%)
58 lines
1.9 KiB
Python
58 lines
1.9 KiB
Python
"""WriterAgent 防御分支覆盖(P0 补测)。
|
|
|
|
覆盖:_resolve_prompt 直返回 Prompt、引擎异常状态无详情、LLM 返回非法 data 触发重试。
|
|
"""
|
|
import pytest
|
|
from types import SimpleNamespace
|
|
|
|
from genesis.inference.types import Prompt
|
|
from genesis.writer.writer_agent import WriterAgent, WriterGenerationError
|
|
from genesis.writer.writer_state import WriterState
|
|
from genesis.writer.models import ChapterSpec, GenerationContext
|
|
|
|
|
|
class _Registry:
|
|
def get_or_create(self, name, template):
|
|
return Prompt(name=name, version="1", template=template)
|
|
|
|
|
|
class _FailedEngine:
|
|
def chat_structured(self, **kw):
|
|
return SimpleNamespace(status="failed", data=None) # 无 error / error_code
|
|
|
|
|
|
class _BadDataEngine:
|
|
def chat_structured(self, **kw):
|
|
return SimpleNamespace(status="ok", data={"title": "x", "blocks": None})
|
|
|
|
|
|
def _ctx():
|
|
return GenerationContext(
|
|
chapter_id="db_design", title="DB 設計",
|
|
template_marker=ChapterSpec(chapter_id="db_design", title="DB 設計",
|
|
section_placeholder=None),
|
|
structured_source="src", write_rules=["W"], design_rules=["D"],
|
|
template_styles={"Heading 1"}, output_language="ja",
|
|
)
|
|
|
|
|
|
def _agent(engine, max_retries=1):
|
|
return WriterAgent(
|
|
session_id="s", engine=engine, prompt_registry=_Registry(),
|
|
state=WriterState(["db_design"]), max_retries=max_retries,
|
|
)
|
|
|
|
|
|
def test_resolve_prompt_passthrough_when_registry_returns_prompt():
|
|
assert isinstance(_agent(_FailedEngine())._resolve_prompt(), Prompt)
|
|
|
|
|
|
def test_engine_failed_status_without_details_raises():
|
|
with pytest.raises(WriterGenerationError, match="failed"):
|
|
_agent(_FailedEngine()).generate_chapter(_ctx())
|
|
|
|
|
|
def test_invalid_llm_data_triggers_retry_and_raises():
|
|
with pytest.raises(WriterGenerationError, match="重试耗尽"):
|
|
_agent(_BadDataEngine()).generate_chapter(_ctx())
|