文笔层:AI 味机检、标点规范化、分块大量扩写(第 1 集成稿 10805 字)
- 修复上次提交把 dfannals/cli.py 写成 0 字节的问题(它是唯一入口,导致管道不可运行) - 性别:解析 <caste>,人物表与写作素材带性别(Ral Fastenhatchets 实为女性) - 新增 dfannals/deslop.py:AI 味机械诊断(硬伤词/句式/标点,按千字密度报告) - 新增 dfannals/normalize.py:标点与结构清理(引号配对、重复段落与句子、模型自加的小节标记) - 新增 dfannals/expand.py 与 prompts/literary-expander.md:按年份场景分块大量扩写 - 专名防幻觉:每块附史料专名白名单,事后按段自动修复可疑专名 - episode 命令并进文笔层(骨架稿另存 .skeleton.md),新增 expand 命令做 A/B 对照 - 新增 notes/switched-threads.md 与 test_deslop / test_normalize 回归测试 - 提交前拦截「已跟踪文件为空」,防止上述事故复发
This commit is contained in:
@@ -75,6 +75,35 @@ def test_figure_ids_excludes_placeholder_and_dedups() -> None:
|
||||
assert len(battle.figure_ids()) == len(set(battle.figure_ids()))
|
||||
|
||||
|
||||
def test_caste_parsed_into_gender() -> None:
|
||||
"""回归:v53 导出用 <caste> 而非 <sex>,漏读会把女性主角写成"他"。"""
|
||||
world = load_world()
|
||||
assert world.figures[12].caste == "FEMALE"
|
||||
assert world.figures[12].gender == "女"
|
||||
assert world.figures[10].gender == "", "未载性别的应返回空串,不能猜"
|
||||
|
||||
|
||||
def test_cast_table_shows_gender() -> None:
|
||||
"""人物表必须带性别列,否则写作者只能猜。"""
|
||||
from collections import Counter
|
||||
|
||||
from dfannals import cast
|
||||
from dfannals import episodes as ep_mod
|
||||
from dfannals.threads import Thread
|
||||
|
||||
world = load_world()
|
||||
thread = Thread(
|
||||
members=[10, 11, 12], interactions=5, turns=1, span=58, first_year=30, last_year=88,
|
||||
types=Counter(), races=Counter(), non_person_races=[], events=world.events,
|
||||
)
|
||||
planned = ep_mod.plan_episodes(thread)
|
||||
text, rows, suspicions = cast.build_cast(world, thread, planned, with_bios=False)
|
||||
assert "| 人物 | 种族 | 性别 |" in text, text.splitlines()[4] if len(text.splitlines()) > 4 else text
|
||||
assert not suspicions
|
||||
elf = next(r for r in rows if r.fid == 12)
|
||||
assert elf.gender == "女"
|
||||
|
||||
|
||||
def test_fake_names_are_caught() -> None:
|
||||
"""反例:凭空编造的人名地名必须被抓出来。"""
|
||||
world = load_world()
|
||||
|
||||
Reference in New Issue
Block a user