feat(toolbox): T6 创作工具箱通用生成器框架 — 8 新生成器 + 声明驱动落地页 + P2 收尾

通用执行路径驱动全部生成器("加生成器=加一份声明"):
- @llm: ww_agents +7 输出 schema + 7 spec(book-title/blurb/name/golden-finger/
  glossary/opening/fine-outline,只声明 tier)+ build_outline_chapter_context
- @backend: ww_skills GeneratorTool 描述符 + TOOLBOX(11) + get_tool;3 通用端点
  GET /skills/toolbox · POST .../skills/{tool_key}/generate(预览不写库,仅记账) ·
  POST .../ingest(复用 continuity 409 + partition_writes 白名单);纯 context 派发
- @frontend: 工具箱落地页 RSC + 声明驱动 GeneratorRunner + lib/toolbox 纯函数
  + LeftNav「工具箱」+ ⌘K nav-toolbox/action-gen-*;legacy 3 跳现页
- @qa: tests/test_t6_toolbox_e2e.py 5 用例真 pg + mock 网关零 token,无端点 bug
- P2 收尾: 限流→decisions.md 记延后(单用户原型);noopener/Committable 早已修

守不变量 #2(只声明 tier)/#3(预览不写库,入库经验收 gate)/#9(缓存前缀)。无 DB 迁移。
门禁绿: 后端 ruff/format/mypy 195/alembic 无漂移/pytest 583;前端 lint/tsc/vitest 279/build。
spec 回写 PRODUCT_SPEC §7 + ARCHITECTURE §7.2 端点表。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yaojia Wang
2026-06-22 20:37:55 +02:00
parent 1f1afa37b6
commit f43ccd293f
46 changed files with 4848 additions and 12 deletions

View File

@@ -336,3 +336,194 @@ class IdeaListResult(BaseModel):
default_factory=list,
description="生成的脑洞清单;无则空列表",
)
# ---- 创作工具箱 · 书名生成器book-titlelight纯预览 writes=[]----
class Title(BaseModel):
"""单个书名候选:书名 + 取名理由(创作工具箱 book-title 产物)。
纯预览产物——不映射任何业务表、不入库(`book_title_spec.writes=[]`,不变量 #3
"""
title: str = Field(description="书名候选")
rationale: str = Field(description="取名理由:为何抓人/契合题材")
class TitleListResult(BaseModel):
"""书名生成器结构化产出一组书名候选T6 创作工具箱)。
声明式只读(不变量 #3纯预览端点同步返回不写任何业务表。
"""
titles: list[Title] = Field(
default_factory=list,
description="生成的书名候选清单;无则空列表",
)
# ---- 创作工具箱 · 简介生成器blurbanalyst纯预览 writes=[]----
class Blurb(BaseModel):
"""单条作品简介:正文 + 切入角度(创作工具箱 blurb 产物)。
纯预览产物——不映射任何业务表、不入库(`blurb_spec.writes=[]`,不变量 #3
"""
text: str = Field(description="简介正文(一段抓人文案)")
angle: str = Field(description="切入角度:从哪个卖点/钩子切入")
class BlurbResult(BaseModel):
"""简介生成器结构化产出多版差异化简介T6 创作工具箱)。
声明式只读(不变量 #3纯预览端点同步返回不写任何业务表。
"""
variants: list[Blurb] = Field(
default_factory=list,
description="生成的简介变体清单;无则空列表",
)
# ---- 创作工具箱 · 取名生成器namelight纯预览 writes=[]----
class NameSuggestion(BaseModel):
"""单条命名建议:名字 + 类别 + 可选说明(创作工具箱 name 产物)。
纯预览产物——不映射任何业务表、不入库(`name_spec.writes=[]`,不变量 #3
`kind` 标注命名对象类别(人物/势力/地点/功法/物品…)。
"""
name: str = Field(description="建议的名字")
kind: str = Field(description="命名对象类别(人物 / 势力 / 地点 / 功法 / 物品 等)")
note: str | None = Field(default=None, description="命名说明(取意/出处,可缺)")
class NameListResult(BaseModel):
"""取名生成器结构化产出一组命名建议T6 创作工具箱)。
声明式只读(不变量 #3纯预览端点同步返回不写任何业务表。
"""
names: list[NameSuggestion] = Field(
default_factory=list,
description="生成的命名建议清单;无则空列表",
)
# ---- 创作工具箱 · 金手指生成器golden-fingerwriter声明式 writes=world_entities----
class GoldenFinger(BaseModel):
"""单个金手指系统:名称 + 机制 + 成长 + 限制(创作工具箱 golden-finger 产物)。
映射 `world_entities`(力量体系类);落库经入库端点(不变量 #3。`limits` = 不可
违背的能力边界/代价,供 continuity 续审引用比对(防能力不符)。
"""
name: str = Field(description="金手指名称")
mechanism: str = Field(description="核心机制:如何运作、触发条件")
growth: str = Field(description="成长路径:随剧情如何升级/进阶")
limits: str = Field(description="限制与代价:能力边界、副作用(防越界,供一致性校验)")
class GoldenFingerResult(BaseModel):
"""金手指生成器结构化产出一组金手指系统T6 创作工具箱)。
声明式 writes不变量 #3本结构是纯产物落 `world_entities` 表经入库端点,
不在 agent 节点直接写库。
"""
systems: list[GoldenFinger] = Field(
default_factory=list,
description="生成的金手指系统清单;无则空列表",
)
# ---- 创作工具箱 · 术语表生成器glossaryanalyst声明式 writes=world_entities----
class GlossaryTerm(BaseModel):
"""单条术语:名称 + 类型 + 定义 + 硬规则(创作工具箱 glossary 产物)。
映射 `world_entities`concept/术语类);`rules` = 该术语的硬规则清单,
对齐 `world_entities.rules`,供 continuity 续审引用比对(不变量 #3
"""
name: str = Field(description="术语名")
type: str = Field(description="术语类型(境界 / 功法 / 货币 / 度量 / 称谓 等)")
definition: str = Field(description="术语定义(一句话释义)")
rules: list[str] = Field(
default_factory=list,
description="该术语的硬规则清单(不可违背设定,供 continuity 校验引用)",
)
class GlossaryResult(BaseModel):
"""术语表生成器结构化产出一组术语T6 创作工具箱)。
声明式 writes不变量 #3本结构是纯产物落 `world_entities` 表经入库端点,
不在 agent 节点直接写库。
"""
terms: list[GlossaryTerm] = Field(
default_factory=list,
description="生成的术语清单;无则空列表",
)
# ---- 创作工具箱 · 开篇生成器openingwriter纯预览 writes=[]----
class Opening(BaseModel):
"""单版开篇正文(创作工具箱 opening 产物)。
纯预览产物——不映射任何业务表、不入库(`opening_spec.writes=[]`,不变量 #3
"""
text: str = Field(description="开篇正文(一段成稿文本)")
class OpeningResult(BaseModel):
"""开篇生成器结构化产出多版开篇T6 创作工具箱)。
声明式只读(不变量 #3纯预览端点同步返回不写任何业务表。
"""
variants: list[Opening] = Field(
default_factory=list,
description="生成的开篇变体清单;无则空列表",
)
# ---- 创作工具箱 · 细纲生成器fine-outlineanalyst声明式 writes=outline----
class Scene(BaseModel):
"""单个场景节拍:序号 + 节拍 + 目的 + 冲突 + 钩子(创作工具箱 fine-outline 产物)。
把某章 outline 的粗节拍展开为细粒度场景;落库经入库端点(不变量 #3
"""
idx: int = Field(description="场景序号章内有序0/1 起均可)")
beat: str = Field(description="场景节拍:本场发生什么")
purpose: str = Field(description="叙事目的:推动主线/塑造人物/铺垫伏笔")
conflict: str = Field(description="本场冲突/张力来源")
hook: str = Field(description="场景钩子:驱动读者读下一场的悬念")
class DetailedOutlineResult(BaseModel):
"""细纲生成器结构化产出某章展开的场景清单T6 创作工具箱)。
声明式 writes不变量 #3本结构是纯产物落 `outline` 表经入库端点,
不在 agent 节点直接写库。
"""
scenes: list[Scene] = Field(
default_factory=list,
description="展开的场景清单;无则空列表",
)