M0:灵台 Kernel 骨架(事件溯源/命台席位/瀑布总线/插件注册)与神识客户端边界,新增 POST /runs 占位闭环与测试,Alembic 基线合并为单一起点

This commit is contained in:
chenxin committed 2026-08-21 21:58:09 +08:00
1 parent 99e55fa0a8
commit 7ef3a15061
23 files changed
+2014 -1399

No files matched your search

+2
View File
@@ -17,6 +17,7 @@ from app.api.v1.endpoints import (
goals,
health,
imports,
kernel_runs,
lorebooks,
mcp,
memory,
@@ -38,6 +39,7 @@ api_router.include_router(characters.router)
api_router.include_router(character_import.router)
api_router.include_router(chat.router)
api_router.include_router(runs.router)
api_router.include_router(kernel_runs.router)
api_router.include_router(memory.router)
api_router.include_router(lorebooks.router)
api_router.include_router(personality.router)
@@ -0,0 +1,55 @@
"""Kernel Run API(rewrite/1.0 新契约首个端点)。
POST /api/v1/runs:创建占位前台 Run(M0 骨架),事件流经既有
GET /api/v1/runs/{run_id}/stream 订阅(SSE + Last-Event-ID 断线续传)。
与旧 runs 路由共存:本模块只新增 POST,不改动旧读端点(M2 重建时收敛)。
"""
from __future__ import annotations
from fastapi import APIRouter, Depends, Request
from pydantic import BaseModel, Field
from sqlalchemy.ext.asyncio import AsyncSession
from app.api.v1.deps import get_current_user
from app.db.session import get_session
from app.kernel import Kernel
from app.schemas.auth import CurrentUser
from app.schemas.runtime import RunResponse
from app.services.characters import resolve_active_character
from app.services.runtime import get_run_response
router = APIRouter(prefix="/runs", tags=["kernel"])
class KernelRunCreate(BaseModel):
"""占位 Run 创建请求:M0 无镜树挂载,prompt 直接作为用户输入。"""
prompt: str = Field(default="你好,请介绍一下你自己。", min_length=1, max_length=8000)
character_id: str | None = Field(default=None, description="缺省用当前激活人物")
def _get_kernel(request: Request) -> Kernel:
kernel: Kernel | None = getattr(request.app.state, "kernel", None)
if kernel is None:
from app.core.errors import AppError
raise AppError("service_unavailable", "Kernel 运行时未就绪。", status_code=503)
return kernel
@router.post("", response_model=RunResponse, status_code=200)
async def create_kernel_run(
payload: KernelRunCreate,
request: Request,
user: CurrentUser = Depends(get_current_user),
db: AsyncSession = Depends(get_session),
) -> RunResponse:
kernel = _get_kernel(request)
character = await resolve_active_character(
db, payload.character_id, owner_scope=user.owner_scope
)
run = await kernel.start_foreground_run(
character_id=character.id, prompt=payload.prompt
)
return await get_run_response(run.id)