docs(prompt-mgmt): 方案A 协同回写 + 补声明 structlog 依赖
- memory/contracts.md:立 C6-ext(load_prompt/SPECS/SCHEMA_CATALOG/
REVIEW_RESERVED_NAMES/SpecResolver + 打包契约)+ 变更日志一笔
- memory/decisions.md:方案A 决策(运行时值金标准/尾换行方案B/守卫前移/
schema 留 Python/同一实例)
- memory/gotchas.md:spec.name 连字符命名 / 改稿须重生成金标准 /
.gitattributes 完整嵌套路径 / wheel artifacts 带 .md / structlog 补声明 /
SpecResolver 零 DB + 精确匹配
- PROGRESS.md:已封板「Prompt 管理重构 + 全量重写」波次
- ARCHITECTURE.md §5.1:补 prompt 外置 + SPECS/SCHEMA_CATALOG/SpecResolver,
内置 agent 计数 8→21
- packages/{llm_gateway,core}/pyproject.toml:补声明 structlog>=24.1
(原直接 import 未声明,靠 apps/api 传递;裸装 import ww_agents 会缺)
This commit is contained in:
@@ -326,9 +326,22 @@
|
||||
- **token 纪律**:job result/status/日志只记章号/计数/标志,绝不含 prompt/正文/token(§5,已断言)。
|
||||
- → 影响 @frontend(链发起页/进度/裁决续跑面板,**非目标本期不做**,契约稳定后 follow-up `pnpm gen:api`);@db/@devops C3(检查点建表迁移 + 可选 jobs 注释)。
|
||||
|
||||
## C6-ext · Prompt 外置 + SpecResolver owner @llm(SPECS/loader/catalog) + @backend(resolver/守卫) 状态: 稳定(方案A,2026-06-24)
|
||||
> 设计真源:`docs/design/prompt-management.md`。纯重构、零功能/schema 变更、零迁移(前端无需 `pnpm gen:api`)。
|
||||
- **`load_prompt(name) -> str`**(`packages/agents/ww_agents/prompt_loader.py`,@llm):按 `prompts/<spec.name>.md` import 期读盘 → 去 BOM(`utf-8-sig`)/CRLF·CR→LF/NFC/`rstrip('\n')` → 内存缓存 → 返回完整 UTF-8 文本;缺文件 `PromptNotFoundError`(fail-fast,不 fallback、不插值)。
|
||||
- **`SPECS: Final[dict[name, AgentSpec]]`**(`specs.py`,@llm):21 内置 spec 集中名册,`assert len(SPECS)==21`;`system_prompt=load_prompt(name)`、`output_schema=SCHEMA_CATALOG[name]`。**不变量**:`SPECS[name] is *_spec`(兼容期同一实例,旧 `from ww_agents import *_spec` 不破);`prompts/<name>.md`/`SPECS[name]`/`SCHEMA_CATALOG[name]` 三集合按 name 恒等。
|
||||
- **`SCHEMA_CATALOG: Final[dict[name, type[BaseModel]|None]]`**(`schema_catalog.py`,@llm):name→output type **唯一真相源**(`refiner=None`);`output_schema_for(name)`。input 全 None,本波不建 input 槽(YAGNI)。
|
||||
- **`REVIEW_RESERVED_NAMES: Final[frozenset]={continuity,foreshadow,style,pace}`**(@llm):四审受信名显式白名单(非派生集合),安全边界锚此。
|
||||
- **`SpecResolver`**(`packages/skills/ww_skills/spec_resolver.py`,@backend):`build(skills)` 纯合并 `dict(SPECS)`+`SkillRegistry`(读路径无冲突校验);`get(name)` 先查内置 `SPECS`(**纯内存、零 DB**)未命中才查 registry,都无→`NOT_FOUND`;`output_schema_for`/`names`/`list_scope`。name **精确字符串相等**(无大小写/连字符归一)。
|
||||
- **守卫前移**:用户 skill 同名内置(`REVIEW_RESERVED_NAMES ∪ set(SPECS)`)在 **`SkillRegistry` 入库/加载校验期**即拒(`AppError(VALIDATION)`,与 `validate_declaration` 同处),**不在 resolver 读路径**——内置 `get` 确定性、零运行时分叉,守不变量 #3。
|
||||
- **打包契约**(@devops):`.gitattributes` 锁 `packages/agents/ww_agents/prompts/*.md text eol=lf`;`packages/agents/pyproject.toml` hatchling `artifacts` 纳入 `prompts/*.md` 随 wheel/sdist 分发;CI `agents-wheel-smoke`(build→裸装→`import ww_agents; assert ww_agents.SPECS`)防 `.md` 漏带(源码树 pytest 测不出)。`packages/{llm_gateway,core}` 补声明 `structlog`(原直接 import 未声明,靠 apps/api 传递)。
|
||||
- 消费方:`toolbox_registry.GeneratorTool.spec` 走 `SPECS["<name>"]`(不再直接 import 生成器 `*_spec`)。**本波不改**编排器(`REVIEW_SPECS`/节点/§6.5 precheck/chain)与 apps/api 3 路由(`toolbox/outline/style`)——兼容期续用 `*_spec`(因同一实例不变量无回归),切 resolver 列后续波次。
|
||||
|
||||
## 契约变更日志(append-only)
|
||||
> 格式:`- [date] @skill 改 Cx:<改了什么> → 影响 <依赖方/任务>`
|
||||
|
||||
- [2026-06-24] @llm/@backend 立 C6-ext(Prompt 外置方案A):21 prompt 散文外置 `prompts/<name>.md` + `load_prompt`/`SPECS`/`SCHEMA_CATALOG`/`REVIEW_RESERVED_NAMES`(@llm)+ `SpecResolver` + SkillRegistry 入库守卫前移 + toolbox 桥接 `SPECS`(@backend)+ `.gitattributes`/wheel package-data/CI 冒烟(@devops)。随后全量重写 21 prompt 内容(任务对齐,schema 契约/不变量保持,金标准 fixture 重生成)。门禁绿:ruff/format/mypy(209)/pytest(744)。→ 影响:后续波次可将编排器 + apps/api 路由切 `SpecResolver` 并删 `*_spec` 导出;前端零影响(GeneratorTool 描述符字段不变)。
|
||||
|
||||
- [2026-06-23] @backend 立 C-Chain(C2):3 端点 + `schemas/chain.py` + `services/{chain_runner,chain_deps}.py` + `jobs` 零迁移复用(加 `status="awaiting_input"` + `JobRepo.set_awaiting`)+ 新 `ErrorCode.CONFLICT`(409) + `project_deps` 加 `build_chain_gateway`/`get_chain_gateway`/`get_digest_gateway_builder`/`get_checkpointer_factory`。OpenAPI 含 2 新 POST(GET /jobs 复用)。门禁绿:ruff/format/mypy(193) 干净 + pytest 600 passed + alembic 无漂移。→ 影响 @frontend(follow-up `pnpm gen:api`)、@db/@devops C3(检查点迁移)。
|
||||
|
||||
- [2026-06-20] @backend 扩 C3:新增 **`GET /projects/{project_id}/chapters/{chapter_no}/injection`**(本章注入透明,B0 读端点)→ `InjectionResponse{project_id, chapter_no, selected:[InjectionEntity{kind,name,reasons[]}], recent_n}`(`schemas/injection.py`,snake_case)。实现仅调既有 `assemble()` 回放确定性 `SelectionTrace`——**无 LLM、无 commit、无 DDL**;项目不存在→404,无大纲→`selected:[]`。reasons 取值同 `SelectionReason`(explicit_beat/main_character/recent_digest/foreshadow_window)。→ 影响 @frontend(已 `pnpm gen:api` + `ChapterAssistant` 消费)。**B0 可控版(PUT override + `select_relevant_entities` 加 pinned/excluded/recent_n + draft 端点同读 override + 持久化)尚未实现,届时再扩本契约。**
|
||||
|
||||
Reference in New Issue
Block a user