141 lines
4.7 KiB
Python
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}
|