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>
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
"""本章注入透明(B0)的响应 schema(C 扩 / ARCH §3.4、§5.3)。
|
||||
"""本章注入透明(B0)的请求/响应 schema(C 扩 / ARCH §3.4、§5.3)。
|
||||
|
||||
snake_case;前端经 OpenAPI 生成 TS 类型消费。改字段 → 前端必须 `pnpm gen:api`。
|
||||
读取无 LLM、无 commit——仅回放 assemble() 的确定性 SelectionTrace(不变量 #6)。
|
||||
读取无 LLM、无 commit——回放 assemble() 的确定性 SelectionTrace(不变量 #6)。
|
||||
可控版(PUT)存作者覆盖:pin 强制纳入 / excluded 强制剔除 / recent_n 覆盖回看章数,
|
||||
本身仍是确定性输入,故「看到的=写章用的」成立。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -10,6 +12,10 @@ import uuid
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
# recent_n 合法区间(回看近况摘要章数)——下限 1,上限防作者误填爆 token。
|
||||
RECENT_N_MIN = 1
|
||||
RECENT_N_MAX = 20
|
||||
|
||||
|
||||
class InjectionEntity(BaseModel):
|
||||
"""一个被注入本章上下文的实体 + 入选理由(喂给透明面板的徽标)。"""
|
||||
@@ -18,14 +24,39 @@ class InjectionEntity(BaseModel):
|
||||
name: str
|
||||
reasons: list[str] = Field(
|
||||
default_factory=list,
|
||||
description="explicit_beat / main_character / recent_digest / foreshadow_window",
|
||||
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 /projects/:id/chapters/:no/injection:本章确定性注入留痕。"""
|
||||
"""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="近况摘要回看章数(确定性选择的默认参数)")
|
||||
recent_n: int = Field(description="生效的近况回看章数(默认或被 override 覆盖后的值)")
|
||||
pinned: list[InjectionEntityRef] = Field(
|
||||
default_factory=list, description="作者强制纳入的实体(回显)"
|
||||
)
|
||||
excluded: list[InjectionEntityRef] = Field(
|
||||
default_factory=list, description="作者强制剔除的实体(回显,供面板恢复)"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user