Files
writer-work-flow/apps/api/ww_api/schemas/injection.py
Yaojia Wang 0d473e726e feat(b0): 注入透明可控版后端 — PUT override(pin/排除/recent_n) + 选择函数加参 + draft 同读
- selection.select_relevant_entities 加 pinned/excluded frozenset 入参;新理由 author_pin(末位)
- assemble 加 override 关键字参(recent_n 覆盖回看章数 + pin/排除);GET/PUT/draft 同读同一覆盖(不变量 #6 作者兜底)
- 新 domain/injection_repo.py(InjectionOverride/EntityRef/SqlInjectionOverrideRepo,upsert 只 flush)
- 新表 chapter_injection(迁移 ad2c4c663daf,唯一 project_id+chapter_no;复用 outline 行已否决)
- PUT/GET injection 端点 + InjectionOverrideRequest/回显 pinned/excluded;recent_n 1..20 校验 422
- 单测:selection pin/排除/exclude>pin + assemble override + 端点 PUT/404/422;regen TS 客户端
- 门禁绿:ruff/format · mypy 163 · alembic 无漂移 · pytest 476

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 11:56:54 +02:00

63 lines
2.4 KiB
Python
Raw Permalink 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.

"""本章注入透明B0的请求/响应 schemaC 扩 / ARCH §3.4、§5.3)。
snake_case前端经 OpenAPI 生成 TS 类型消费。改字段 → 前端必须 `pnpm gen:api`。
读取无 LLM、无 commit——回放 assemble() 的确定性 SelectionTrace不变量 #6
可控版PUT存作者覆盖pin 强制纳入 / excluded 强制剔除 / recent_n 覆盖回看章数,
本身仍是确定性输入,故「看到的=写章用的」成立。
"""
from __future__ import annotations
import uuid
from pydantic import BaseModel, Field
# recent_n 合法区间(回看近况摘要章数)——下限 1上限防作者误填爆 token。
RECENT_N_MIN = 1
RECENT_N_MAX = 20
class InjectionEntity(BaseModel):
"""一个被注入本章上下文的实体 + 入选理由(喂给透明面板的徽标)。"""
kind: str = Field(description="character / world_entity")
name: str
reasons: list[str] = Field(
default_factory=list,
description="explicit_beat/main_character/recent_digest/foreshadow_window/author_pin",
)
class InjectionEntityRef(BaseModel):
"""作者 pin/排除点名的实体引用kind + name"""
kind: str = Field(description="character / world_entity")
name: str
class InjectionOverrideRequest(BaseModel):
"""PUT /projects/:id/chapters/:no/injection作者对本章注入的覆盖。
pinned 强制纳入(加 author_pin 理由excluded 强制剔除recent_n 覆盖近况回看章数
None=用默认)。空覆盖 = 纯自动选择。
"""
pinned: list[InjectionEntityRef] = Field(default_factory=list)
excluded: list[InjectionEntityRef] = Field(default_factory=list)
recent_n: int | None = Field(default=None, ge=RECENT_N_MIN, le=RECENT_N_MAX)
class InjectionResponse(BaseModel):
"""GET/PUT /projects/:id/chapters/:no/injection本章注入留痕 + 作者覆盖回显。"""
project_id: uuid.UUID
chapter_no: int
selected: list[InjectionEntity] = Field(default_factory=list)
recent_n: int = Field(description="生效的近况回看章数(默认或被 override 覆盖后的值)")
pinned: list[InjectionEntityRef] = Field(
default_factory=list, description="作者强制纳入的实体(回显)"
)
excluded: list[InjectionEntityRef] = Field(
default_factory=list, description="作者强制剔除的实体(回显,供面板恢复)"
)