Files
matrix-show/backend/app/routes/character.py
T
2026-06-04 17:59:53 +08:00

141 lines
4.7 KiB
Python

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.database import get_session
from app.models.orm import Character
from app.models.schemas import (
CharacterResponse,
CharacterCreate,
CharacterStatus,
CharacterSpeakRequest,
SoulUpdateRequest,
CharacterGenerateRequest,
)
from app.services.character_generator import character_generator
from app.services.hermes_client import hermes_client
from app.services.soul_generator import soul_generator
router = APIRouter()
@router.get("", response_model=list[CharacterResponse])
async def list_characters(session: AsyncSession = Depends(get_session)):
result = await session.execute(select(Character))
return list(result.scalars().all())
@router.get("/{character_id}", response_model=CharacterResponse)
async def get_character(character_id: str, session: AsyncSession = Depends(get_session)):
result = await session.execute(select(Character).where(Character.id == character_id))
character = result.scalars().first()
if not character:
raise HTTPException(status_code=404, detail="Character not found")
return character
@router.put("/{character_id}/soul")
async def update_character_soul(
character_id: str,
req: SoulUpdateRequest,
session: AsyncSession = Depends(get_session),
):
result = await session.execute(select(Character).where(Character.id == character_id))
character = result.scalars().first()
if not character:
raise HTTPException(status_code=404, detail="Character not found")
previous = character.hermes_profile
character.soul_md = req.soul_md
character.knowledge_base = req.knowledge_base
await hermes_client.create_profile(previous, req.soul_md)
await session.commit()
await session.refresh(character)
return {"ok": True, "character_id": character_id}
@router.post("/{character_id}/speak")
async def character_speak(
character_id: str,
req: CharacterSpeakRequest,
session: AsyncSession = Depends(get_session),
):
result = await session.execute(select(Character).where(Character.id == character_id))
character = result.scalars().first()
if not character:
raise HTTPException(status_code=404, detail="Character not found")
prompt = req.prompt or "根据当前剧本进度自然发言"
response = await hermes_client.chat(character.hermes_profile, prompt)
return {
"character_id": character_id,
"character_name": character.name,
"response": response,
}
@router.post("/{character_id}/profile")
async def create_character_profile(
character_id: str,
session: AsyncSession = Depends(get_session),
):
result = await session.execute(select(Character).where(Character.id == character_id))
character = result.scalars().first()
if not character:
raise HTTPException(status_code=404, detail="Character not found")
success = await character_generator.create_profile(character)
await session.commit()
return {"ok": success, "character_id": character_id}
@router.post("/generate", response_model=list[CharacterResponse])
async def generate_characters(
req: CharacterGenerateRequest,
session: AsyncSession = Depends(get_session),
):
result = await session.execute(select(Character).where(Character.script_id == req.script_id))
existing = list(result.scalars().all())
for char in existing:
await session.delete(char)
await session.commit()
character_data = [{"name": name} for name in req.character_names]
characters = await character_generator.generate_characters(
session, req.script_id, character_data
)
return characters
@router.post("/{character_id}/status")
async def update_character_status(
character_id: str,
status: CharacterStatus,
session: AsyncSession = Depends(get_session),
):
result = await session.execute(select(Character).where(Character.id == character_id))
character = result.scalars().first()
if not character:
raise HTTPException(status_code=404, detail="Character not found")
character.status = status
await session.commit()
await session.refresh(character)
return {"ok": True, "status": character.status.value}
@router.delete("/{character_id}")
async def delete_character(character_id: str, session: AsyncSession = Depends(get_session)):
result = await session.execute(select(Character).where(Character.id == character_id))
character = result.scalars().first()
if not character:
raise HTTPException(status_code=404, detail="Character not found")
await character_generator.delete_profile(character)
await session.delete(character)
await session.commit()
return {"ok": True}