M7:形仪与语音——真形锚点、候选定相、声音档案与克隆授权、ASR 接入
- 形仪域 domains/xingyi:form_anchors(稳定辨识特征/年龄表现/许可禁忌/可变范围——生成内容不可静默覆盖锚点);forms(主仪/化仪/文字形仪,candidate→adopt 定相治理:未定相不进呈现位、主仪唯一、新主仪自动退役旧主仪);voice_profiles(三来源,授权克隆必填用途与传播范围,revoke-grant 撤回立即生效,assert-usable 合成前置校验拒绝撤回/过期) - ASR:元炁 SenseVoice /v1/audio/transcriptions 透传(Whisper 兼容 multipart);YUANQI_BASE_URL 未配置时 503 不降级不伪造——多模态关闭纪律 - 前端形仪工坊(人物详情页):真形锚点编辑(特征逐行解析)/候选登记定相废弃/声音档案建立与授权撤回;头像呈现位改走定相主仪(forms/primary);xingyi api 库 + mock + 组件 4 用例 - 退役:旧 avatar 模块(services/endpoints/avatar、avatar_dir 配置、avatar_url 字段、前端直传组件与测试) - 验收(test_m7_xingyi 三用例):未定相不成为正式形仪(含主仪唯一与旧主仪 retired 断言);克隆授权可撤回(缺用途拒/撤回即拒/过期同理/预设不受约束);关闭全部多模态后文字相伴完整可用(ASR 503 时镜树缘契百工照常——回归) - 四套件:后端 376、前端 203、BFF 4、神识 5 包全绿(2 个预存环境失败不变);迁移 008 净库+±1 干净
This commit is contained in:
1 parent
7e23d6fa84
commit
b419e0afde
30 files changed
+1876
-468
No files matched your search
@@ -5,7 +5,6 @@ from fastapi import APIRouter
|
||||
from app.api.v1.endpoints import (
|
||||
admin,
|
||||
auth,
|
||||
avatar,
|
||||
character_import,
|
||||
characters,
|
||||
|
||||
@@ -21,6 +20,7 @@ from app.api.v1.endpoints import (
|
||||
baigong,
|
||||
hetu,
|
||||
soul,
|
||||
xingyi,
|
||||
yuanqi,
|
||||
mirror_trees,
|
||||
mcp,
|
||||
@@ -44,6 +44,7 @@ api_router.include_router(kernel_runs.router)
|
||||
api_router.include_router(me.router)
|
||||
api_router.include_router(hetu.world_router)
|
||||
api_router.include_router(soul.soul_router)
|
||||
api_router.include_router(xingyi.form_router)
|
||||
api_router.include_router(yuanqi.cov_router)
|
||||
for _baigong_r in baigong.routers:
|
||||
api_router.include_router(_baigong_r)
|
||||
@@ -62,4 +63,3 @@ api_router.include_router(imports.router)
|
||||
api_router.include_router(events.router)
|
||||
api_router.include_router(goals.router)
|
||||
api_router.include_router(admin.router)
|
||||
api_router.include_router(avatar.router)
|
||||
@@ -1,47 +0,0 @@
|
||||
"""角色头像 API。
|
||||
|
||||
上传与获取角色头像图片文件。
|
||||
"""
|
||||
|
||||
from fastapi import APIRouter, Depends, File, UploadFile
|
||||
|
||||
from app.api.v1.deps import get_current_user
|
||||
from app.schemas.auth import CurrentUser
|
||||
from app.services.avatar import (
|
||||
get_avatar_response,
|
||||
upload_avatar,
|
||||
)
|
||||
|
||||
router = APIRouter(prefix="/characters", tags=["characters"])
|
||||
|
||||
|
||||
@router.post("/{character_id}/avatar")
|
||||
async def upload_character_avatar(
|
||||
character_id: str,
|
||||
file: UploadFile = File(..., description="头像图片,支持 JPG/PNG/WebP,最大 5MB。"),
|
||||
current_user: CurrentUser = Depends(get_current_user),
|
||||
) -> dict:
|
||||
"""上传角色头像。
|
||||
|
||||
支持的格式:JPEG、PNG、WebP。最大 5MB。
|
||||
新头像会替换旧头像(同角色只保留一张)。
|
||||
"""
|
||||
content = await file.read()
|
||||
avatar_url = await upload_avatar(
|
||||
character_id=character_id,
|
||||
content=content,
|
||||
content_type=file.content_type or "image/jpeg",
|
||||
owner_scope=current_user.owner_scope,
|
||||
)
|
||||
return {"avatar_url": avatar_url}
|
||||
|
||||
|
||||
@router.get("/{character_id}/avatar")
|
||||
async def get_character_avatar(
|
||||
character_id: str,
|
||||
) -> object:
|
||||
"""获取角色头像图片。
|
||||
|
||||
返回原始图片文件。无头像时返回 404。
|
||||
"""
|
||||
return await get_avatar_response(character_id)
|
||||
@@ -0,0 +1,5 @@
|
||||
"""形仪路由(域实现见 app/domains/xingyi/api.py)。"""
|
||||
|
||||
from app.domains.xingyi.api import form_router
|
||||
|
||||
__all__ = ["form_router"]
|
||||
Reference in new issue
Block a user