feat(ux): T4-b 后端 — draft 端点接收本章指令 directive 直通 assemble(volatile)

assemble/_build_volatile 加 directive 参数(仅入 volatile,守缓存前缀不变量 #9);stream_draft 加可选 body {directive} 透传;不持久化、无迁移;directive 长度入 log 不记原文。新 DraftStreamRequest schema + 重生成 TS 客户端。后端门禁绿: ruff/mypy/pytest。契约记 memory/contracts.md。
This commit is contained in:
Yaojia Wang
2026-06-20 18:25:00 +02:00
parent 8779530806
commit 2155193cdc
7 changed files with 94 additions and 5 deletions

View File

@@ -104,6 +104,7 @@ def _build_volatile(
foreshadows: list[ForeshadowView],
digests: list[DigestView],
beats: dict[str, Any],
directive: str | None = None,
) -> str:
fore_lines = [
f"【伏笔】{f.code} {f.title} [{f.status}]"
@@ -113,6 +114,8 @@ def _build_volatile(
f"{d.chapter_no}章:{_ser(d.facts)}" for d in sorted(digests, key=lambda d: d.chapter_no)
]
sections = [
# 作者本章指令领衔——易变的每章输入,只入 volatile断点后守缓存前缀不变量 #9。
_section("本章指令", directive.strip()) if directive and directive.strip() else None,
# 写章指令始终在场——保证 volatile断点后的 input永不为空修空 prompt 400
_section("写作指令", f"请创作第 {chapter_no} 章的正文。"),
_section("本章注入卡片", cards),
@@ -130,11 +133,15 @@ async def assemble(
recent_k: int = RECENT_DIGEST_COUNT,
*,
override: InjectionOverride | None = None,
directive: str | None = None,
) -> AssembledContext:
"""组装本章 prompt 上下文(确定性、可缓存)。
`override`B0 可控版作者覆盖也是确定性输入pin 强制纳入 / excluded 强制剔除 /
recent_n 覆盖近况回看章数。draft 与注入读端点传同一覆盖,故「看到的=写章用的」(不变量 #6
`directive`T4-b 本章指令)是临时的每章输入——只入 volatile断点后绝不污染
stable_core 缓存前缀(不变量 #9不持久化。
"""
# recent_n 覆盖优先于默认 recent_k非正值视为未设守住至少回看若干章
effective_k = override.recent_n if (override and override.recent_n) else recent_k
@@ -171,6 +178,8 @@ async def assemble(
stable_core = _build_stable(spec, world_entities, main_characters, style, rules)
cards = render_cards(selection, characters, world_entities)
volatile = _build_volatile(chapter_no, cards, foreshadows, recent_digests, outline.beats)
volatile = _build_volatile(
chapter_no, cards, foreshadows, recent_digests, outline.beats, directive
)
return AssembledContext(stable_core=stable_core, volatile=volatile, selection=selection)