- models: CHAPTER_SHEET_TYPES/CHAPTER_IMPACT_ELEMENT 章节→数据映射(design §6.8 ①)
- models: _format_chapter_data 按章定向渲染 ExcelTable 为 Markdown;GENERIC 自由記述作通用背景
- models: _format_impact 支持按 ElementType 过滤(章节级影响上下文)
- writer_agent: {{source}}(全量repr) → {{data}}(章节数据);新增【主题约束】
- writer_agent: 关键修复——真实 PromptRegistry.get 返回模板字符串,
引擎对 str 不做变量渲染,LLM 实际收到的是 {{占位符}} 原文;
_resolve_prompt 统一包装为 Prompt 对象保证渲染
- 真实试运行验证:13 章主题全部正确、引用影响调查数据、语言漂移消除
88 lines
3.6 KiB
Python
88 lines
3.6 KiB
Python
from types import SimpleNamespace
|
|
|
|
from genesis.data_models import ParsedTemplate, ChapterMarker
|
|
from genesis.writer.context_builder import build_contexts
|
|
from genesis.writer.models import GenerationContext
|
|
|
|
|
|
def _ss():
|
|
template = ParsedTemplate(
|
|
file_name="t.docx",
|
|
sections=[
|
|
ChapterMarker(type="heading", name="はじめに", level=1),
|
|
ChapterMarker(type="placeholder", name="section:introduction", level=0),
|
|
],
|
|
placeholders={},
|
|
styles={"defined": ["Heading1"], "used": ["Heading1", "Normal"]},
|
|
)
|
|
return SimpleNamespace(template=template)
|
|
|
|
|
|
def test_build_contexts_maps_chapters():
|
|
ctxs = build_contexts(_ss(), samples_dir="nonexistent_dir_xyz")
|
|
assert len(ctxs) == 1
|
|
c = ctxs[0]
|
|
assert isinstance(c, GenerationContext)
|
|
assert c.chapter_id == "introduction"
|
|
assert c.write_rules == [] # 样本缺失 -> 空
|
|
assert c.design_rules == []
|
|
assert c.template_styles == {"Heading1", "Normal"}
|
|
assert c.template_marker.section_placeholder == "section:introduction"
|
|
|
|
|
|
def test_build_contexts_without_impact_report_is_none():
|
|
ctxs = build_contexts(_ss(), samples_dir="nonexistent_dir_xyz")
|
|
assert ctxs[0].impact_report is None
|
|
|
|
|
|
def test_build_contexts_carries_impact_report():
|
|
from genesis.data_models import ChangeAnalysis, ChangeElement, ChangeType, ImpactReport
|
|
ca = ChangeAnalysis(project_type="enhancement", new_elements=[], modified_elements=[],
|
|
deleted_elements=[], unchanged_elements=[], warnings=[])
|
|
report = ImpactReport(metadata={"version": "v1"}, change_analysis=ca, summary={})
|
|
ss = _ss()
|
|
ss.impact_report = report
|
|
ctxs = build_contexts(ss, samples_dir="nonexistent_dir_xyz")
|
|
assert ctxs[0].impact_report is report
|
|
assert "project_type" in ctxs[0].to_vars()["impact"] or ctxs[0].to_vars()["impact"] != ""
|
|
|
|
|
|
def test_build_contexts_vars_data_scoped_per_chapter():
|
|
"""集成:多章模板 + FUNCTION/DB 表 → 各章 to_vars()['data'] 按章节定向。"""
|
|
from genesis.data_models import (
|
|
CellValue, ExcelTable, Provenance, SheetType, StructuredSource,
|
|
)
|
|
template = ParsedTemplate(
|
|
file_name="t.docx",
|
|
sections=[
|
|
ChapterMarker(type="heading", name="機能一覧", level=1),
|
|
ChapterMarker(type="placeholder", name="section:function_list", level=0),
|
|
ChapterMarker(type="heading", name="DB設計", level=1),
|
|
ChapterMarker(type="placeholder", name="section:db_design", level=0),
|
|
],
|
|
placeholders={},
|
|
styles={"used": ["Heading1"]},
|
|
)
|
|
|
|
def cell(v):
|
|
return CellValue(value=v, provenance=Provenance("f.xlsx", "s", 1, "A", "列"))
|
|
|
|
ss = StructuredSource(
|
|
tables=[
|
|
ExcelTable("機能一覧", SheetType.FUNCTION, "openpyxl",
|
|
["機能ID", "機能名"],
|
|
[{"機能ID": cell("F001"), "機能名": cell("止损风控")}]),
|
|
ExcelTable("DB定義", SheetType.DATABASE, "openpyxl",
|
|
["テーブルID", "テーブル名"],
|
|
[{"テーブルID": cell("T001"), "テーブル名": cell("trade_order")}]),
|
|
],
|
|
template=template, rule_docs=[], image_analyses=[],
|
|
existing_system=None, comments=[],
|
|
)
|
|
ctxs = build_contexts(ss, samples_dir="nonexistent_dir_xyz")
|
|
by_id = {c.chapter_id: c for c in ctxs}
|
|
fn = by_id["function_list"].to_vars()["data"]
|
|
db = by_id["db_design"].to_vars()["data"]
|
|
assert "F001" in fn and "trade_order" not in fn
|
|
assert "T001" in db and "止损风控" not in db
|