Files
writer-work-flow/apps/api/ww_api/schemas/style.py

83 lines
3.1 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.

"""文风学习 + 回炉端点的请求/响应 schemaC3 扩 / ARCH §7.2 / UX §6.9 / §8.3)。
snake_case命名契约见 memory/gotchas。前端经 OpenAPI→TS 客户端消费——改字段
须 `pnpm gen:api` 重生成。
"""
from __future__ import annotations
import uuid
from typing import Annotated, Literal
from pydantic import BaseModel, Field, StringConstraints
# 请求文本长度上界CR-H9防超长入参空跑 LLM/DoS。选段/样本 20k 字符,样本列表 ≤20 条。
_SEGMENT_MAX = 20_000
_SAMPLE_MAX = 20_000
_SAMPLES_LIST_MAX = 20
# 预检澄清沿用相同选段上界DRY指令短。
_MAX_CLARIFY_SEGMENT_LEN = _SEGMENT_MAX
_MAX_CLARIFY_INSTRUCTION_LEN = 2000
class StyleLearnRequest(BaseModel):
"""学文风:上传样本正文(前端可读文件转文本)+ 模式(首学 / 更新)。"""
# 同时约束**列表条数**与**每条样本长度**(最大 DoS 面:多条超长正文)。
samples: list[Annotated[str, StringConstraints(max_length=_SAMPLE_MAX)]] = Field(
min_length=1, max_length=_SAMPLES_LIST_MAX
)
mode: Literal["create", "update"] = "create"
class StyleLearnResponse(BaseModel):
"""学文风受理:返回 job_id长任务走 `GET /jobs/{id}` 轮询)。"""
job_id: uuid.UUID
class DimensionEntry(BaseModel):
"""单个文风维度:名称 + 判定值 + 原文证据摘录(强类型,替代裸 dict[str, Any])。"""
name: str
value: str
evidence: list[str] = Field(default_factory=list)
class StyleFingerprintResponse(BaseModel):
"""最新文风指纹(`GET /style`):完整 16 维(名称/值/证据)+ 版本(对齐 UX §6.9)。
DB 存两列并行 dict`{name:value}` + `{name:[evidence]}`);响应合并为
`list[DimensionEntry]`,给 TS 客户端强类型(替代弱类型 `dict[str, Any]`)。
"""
dimensions: list[DimensionEntry] = Field(default_factory=list)
version: int
class RefineRequest(BaseModel):
"""回炉:重写选中段(可选改写指令)。"""
segment: str = Field(min_length=1, max_length=_SEGMENT_MAX)
# CR-H9 收尾:再沟通意见喂 LLM加上界与 clarify instruction 同口径 2000
instruction: str | None = Field(default=None, max_length=_MAX_CLARIFY_INSTRUCTION_LEN)
class RefineResponse(BaseModel):
"""回炉结果:原段 + 重写段(不写库,作者采纳经既有 draft 自动保存合入)。"""
original: str
refined: str
class RefineClarifyRequest(BaseModel):
"""润色预检澄清:选段 + 再沟通意见WFW-9 M1 路线A 两阶段之「问题」阶段)。
与 `RefineRequest` 独立——预检只判「意见清不清楚」,不改正文。`instruction` 为作者的
再沟通意见(可空/极短,正是触发反问的场景);带长度上界防超长入参。响应=`ClarifyDecision`
(在 ww_agents端点直接返回供前端 gen:api 生成强类型客户端)。
"""
segment: str = Field(min_length=1, max_length=_MAX_CLARIFY_SEGMENT_LEN)
instruction: str = Field(default="", max_length=_MAX_CLARIFY_INSTRUCTION_LEN)