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:
@@ -6,7 +6,10 @@ from collections.abc import AsyncIterator
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import JSONResponse
|
||||
from ww_config import get_settings
|
||||
from ww_core.domain.job_repo import SqlJobRepo
|
||||
from ww_db import get_sessionmaker
|
||||
from ww_shared import AppError, ErrorBody, ErrorEnvelope
|
||||
|
||||
@@ -14,11 +17,15 @@ from ww_api.logging_config import configure_logging, get_logger
|
||||
from ww_api.middleware import request_id_middleware
|
||||
from ww_api.routers import (
|
||||
foreshadow,
|
||||
generation,
|
||||
health,
|
||||
jobs,
|
||||
kimi_oauth,
|
||||
outline,
|
||||
projects,
|
||||
rules,
|
||||
settings_providers,
|
||||
style,
|
||||
)
|
||||
from ww_api.services.project_deps import seed_stub_user
|
||||
|
||||
@@ -31,11 +38,28 @@ async def _lifespan(app: FastAPI) -> AsyncIterator[None]:
|
||||
# 幂等 seed 单用户 stub——所有 owner_id FK 依赖它(见 memory/gotchas)。
|
||||
async with get_sessionmaker()() as session:
|
||||
await seed_stub_user(session)
|
||||
# zombie reaper(M4-d / §7.4 缓解):进程重启会丢未跑完的 BackgroundTask,把残留
|
||||
# status=running 的 job 标 failed(让用户看到失败可重试,而非进度条永转)。自 commit、幂等。
|
||||
async with get_sessionmaker()() as session:
|
||||
reaped = await SqlJobRepo(session).reap_zombies()
|
||||
if reaped:
|
||||
log.info("job_zombies_reaped", count=reaped)
|
||||
yield
|
||||
|
||||
|
||||
def create_app() -> FastAPI:
|
||||
app = FastAPI(title="网文创作工作流 API", version="0.0.0", lifespan=_lifespan)
|
||||
# CORS:前端(Next.js)与 API 分端口/跨源,浏览器端 `api.POST/PUT` 需 CORS 放行
|
||||
# (RSC 服务端取数同源、无需 CORS,故此前同进程测试从未暴露此缺口)。原型单用户、
|
||||
# 本地开发:放行 localhost:3000;可经 env `CORS_ORIGINS`(逗号分隔)覆盖。
|
||||
settings = get_settings()
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=settings.cors_origins,
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
app.middleware("http")(request_id_middleware)
|
||||
|
||||
@app.exception_handler(AppError)
|
||||
@@ -57,7 +81,12 @@ def create_app() -> FastAPI:
|
||||
app.include_router(projects.router)
|
||||
app.include_router(foreshadow.router)
|
||||
app.include_router(outline.router)
|
||||
app.include_router(rules.router)
|
||||
app.include_router(style.router)
|
||||
app.include_router(generation.router)
|
||||
app.include_router(generation.skills_router)
|
||||
app.include_router(settings_providers.router)
|
||||
app.include_router(kimi_oauth.router)
|
||||
return app
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user