Files
writer-work-flow/packages/agents/ww_agents/schema_catalog.py
Yaojia Wang 1652ad9d20 feat(backend): AI 反问澄清预检端点——refine 侧结构化 clarify(WFW-9 M1,路线A 两阶段)
润色「再沟通」意见含糊时先反问给选项(路线A:问题走独立非流式 JSON 预检端点,正文仍走
既有 refine 一字不改)。新增:
- ClarifyDecision/ClarifyQuestion/ClarifyOption 结构化 schema(既有 output-schema 处,供
  producer 与端点共用);clarify_refine.md 教条(含糊→need_clarification+≤1问+2–4锚定选项+
  自由输入;明确→verification 放行;防循环);注册 clarify_refine_spec(analyst 档,#24)+
  SCHEMA_CATALOG + 重生成金标准。
- clarify_node:build_clarify_request 纯函数(缓存前缀不含易变) + run_clarify(gateway.run
  结构化,判别/校验失败确定性回退 need_clarification=false,只读不写库)。
- POST /projects/{id}/chapters/{no}/refine/clarify → ClarifyDecision(analyst 网关,404/503,
  末尾 commit 记账)。**既有 refine 端点/RefineRequest/Response 完全未改**。
门禁绿:ruff/mypy 227/pytest 900(+test_clarify_spec/_node/style clarify)/alembic 无漂移。
2026-07-08 08:47:13 +02:00

74 lines
2.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""`SCHEMA_CATALOG`name → output schema 的唯一真相源Prompt 外置方案A · 步4
Pydantic 类型承载结构化解析与 `isinstance` 校验,无法从文本推导、无法运行时安全构造,
必须留 Python。`SPECS[name].output_schema` 一律从这里派生(单向派生,避免双真相)。
`input_schema` 全 23 个恒为 None入参为序列化文本本波不建入参槽YAGNI
`refiner` 是唯一纯文本 writer`None` 是合法值(无结构化 schema
"""
from __future__ import annotations
from typing import Final
from pydantic import BaseModel
from .schemas import (
BlurbResult,
BookTeardownResult,
CharacterGenResult,
CharacterizationReview,
ClarifyDecision,
ContinuationResult,
ContinuityReview,
DeAiResult,
DetailedOutlineResult,
ForeshadowReview,
GlossaryResult,
GoldenFingerResult,
IdeaListResult,
NameListResult,
OpeningResult,
OutlineResult,
PaceReview,
PolishResult,
ProjectPlanResult,
StyleDriftReview,
StyleFingerprintResult,
TitleListResult,
WorldGenResult,
)
# name → output_schemainput 全 None本波不建入参槽——YAGNI
SCHEMA_CATALOG: Final[dict[str, type[BaseModel] | None]] = {
"continuity": ContinuityReview,
"outliner": OutlineResult,
"foreshadow": ForeshadowReview,
"pace": PaceReview,
"characterization": CharacterizationReview,
"style_extract": StyleFingerprintResult,
"style": StyleDriftReview,
"refiner": None, # 唯一纯文本 writerNone 是合法值
"worldbuilder": WorldGenResult,
"character-gen": CharacterGenResult,
"brainstorm": IdeaListResult,
"book-title": TitleListResult,
"blurb": BlurbResult,
"name": NameListResult,
"golden-finger": GoldenFingerResult,
"glossary": GlossaryResult,
"opening": OpeningResult,
"fine-outline": DetailedOutlineResult,
"continue": ContinuationResult,
"expand": PolishResult,
"de-ai": DeAiResult,
"teardown": BookTeardownResult,
"project-plan": ProjectPlanResult,
"clarify_refine": ClarifyDecision,
}
def output_schema_for(name: str) -> type[BaseModel] | None:
"""name → output schema精确字符串相等命中未知 name → KeyError"""
return SCHEMA_CATALOG[name]