feat: M4 文风 + M5 生成/多provider/Skill + Kimi Code 订阅接入 + 本地联调修复
M4(文风): style-auditor 双轨(提取指纹/漂移第四审)+ jobs 长任务框架(zombie reaper) + 回炉 refine + GET /style read-back。 M5(生成+扩展): worldbuilder/character-gen(入库 continuity 409 gate + partition_writes 白名单 + schema→JSONB 形变); 网关多 provider 回退链/熔断/能力降级(Anthropic/Gemini 适配器);Skill registry + 表权限沙箱 + 规则; 前端 角色生成器/世界观/Codex/规则页/技能库/⌘K 命令面板。 K1(Kimi Code 订阅接入): OAuth device-flow(kimi-code)+ 静态 Console key(kimi-code-key)两路径; coding 端点 KimiCLI 伪造头(实测 UA allow-list 门禁,缺则 403)+ JSON 模式结构化(thinking ⊥ tool_choice)。 本地联调修复: CORS 中间件;assemble 注入 premise+「写第N章」指令(修空 prompt 400); GET /outline·/draft read-back + 大纲/工作台/审稿页重载;写页 client/server 常量边界 + notFound 健壮化; 字数 toLocaleString locale 水合;审稿页终稿从已存草稿 seed(修 accept 422)。 门禁: backend ruff/mypy(157)/alembic 无漂移/pytest 451 · frontend lint/tsc/vitest/build。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
53
apps/api/ww_api/routers/rules.py
Normal file
53
apps/api/ww_api/routers/rules.py
Normal file
@@ -0,0 +1,53 @@
|
||||
"""规则端点(C3 扩 / PRODUCT_SPEC §7 `POST /projects/:id/rules`;不变量 #3)。
|
||||
|
||||
POST /projects/:id/rules:作者显式加规则——审稿发现的问题/亮点随手沉淀为项目规则。
|
||||
写一行 `rules`(level + content),喂给 assemble 的四级合并(`merge_rules`)。
|
||||
|
||||
加规则是**作者显式动作**(不变量 #3:规则入库不经 AI 静默写库)。`level` 合法性由
|
||||
`RuleCreateRequest` 的 Literal 校验(非法 → FastAPI 422)。
|
||||
|
||||
提交边界:`RuleWriteRepo.create` 只 `flush()`,端点写后 `await session.commit()`
|
||||
(仿 foreshadow/outline 写侧,见 memory/gotchas)。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from ww_core.domain import RuleWriteRepo
|
||||
from ww_db import get_session
|
||||
|
||||
from ww_api.logging_config import get_logger
|
||||
from ww_api.schemas.rules import RuleCreateRequest, RuleView
|
||||
from ww_api.services.project_deps import get_rule_write_repo
|
||||
|
||||
log = get_logger("ww.api.rules")
|
||||
|
||||
router = APIRouter(prefix="/projects", tags=["rules"])
|
||||
|
||||
RuleWriteRepoDep = Annotated[RuleWriteRepo, Depends(get_rule_write_repo)]
|
||||
SessionDep = Annotated[AsyncSession, Depends(get_session)]
|
||||
|
||||
|
||||
@router.post("/{project_id}/rules", status_code=201)
|
||||
async def create_rule(
|
||||
project_id: uuid.UUID,
|
||||
body: RuleCreateRequest,
|
||||
request: Request,
|
||||
repo: RuleWriteRepoDep,
|
||||
session: SessionDep,
|
||||
) -> RuleView:
|
||||
"""新增一条规则(201)。非法 level / 空 content → FastAPI 422。"""
|
||||
request_id = getattr(request.state, "request_id", None)
|
||||
view = await repo.create(project_id, level=body.level, content=body.content)
|
||||
await session.commit()
|
||||
log.info(
|
||||
"rule_created",
|
||||
project_id=str(project_id),
|
||||
request_id=request_id,
|
||||
level=body.level,
|
||||
)
|
||||
return RuleView(level=view.level, content=view.content)
|
||||
Reference in New Issue
Block a user