56 lines
2.0 KiB
Python
56 lines
2.0 KiB
Python
"""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)
|