init
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
import logging
|
||||
import random
|
||||
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.models.orm import Character
|
||||
from app.models.schemas import CharacterRole
|
||||
from app.services.hermes_client import hermes_client
|
||||
from app.services.soul_generator import soul_generator
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CharacterGenerator:
|
||||
async def generate_characters(
|
||||
self,
|
||||
session: AsyncSession,
|
||||
script_id: str,
|
||||
characters_data: list[dict],
|
||||
is_json: bool = False,
|
||||
) -> list[Character]:
|
||||
characters = []
|
||||
killer_index = random.randint(0, len(characters_data) - 1) if len(characters_data) > 1 else 0
|
||||
|
||||
for i, char_data in enumerate(characters_data):
|
||||
role = CharacterRole.KILLER if i == killer_index else CharacterRole.SUSPECT
|
||||
if is_json and "role" in char_data:
|
||||
role = CharacterRole(char_data["role"]) if char_data["role"] in [r.value for r in CharacterRole] else role
|
||||
|
||||
name = char_data.get("name", f"角色{i + 1}")
|
||||
profile_name = name.lower().replace(" ", "_").replace("·", "_")
|
||||
|
||||
character = Character(
|
||||
script_id=script_id,
|
||||
name=name,
|
||||
role=role,
|
||||
personality=char_data.get("personality", ""),
|
||||
speaking_style=char_data.get("speaking_style", ""),
|
||||
background=char_data.get("background", ""),
|
||||
secret=char_data.get("secret", ""),
|
||||
motive=char_data.get("motive", ""),
|
||||
hermes_profile=profile_name,
|
||||
is_revealed_killer=False,
|
||||
)
|
||||
session.add(character)
|
||||
characters.append(character)
|
||||
|
||||
await session.commit()
|
||||
for character in characters:
|
||||
await session.refresh(character)
|
||||
|
||||
return characters
|
||||
|
||||
async def create_profile(self, character: Character) -> bool:
|
||||
soul_content = soul_generator.generate(
|
||||
name=character.name,
|
||||
personality=character.personality,
|
||||
speaking_style=character.speaking_style,
|
||||
background=character.background,
|
||||
secret=character.secret,
|
||||
motive=character.motive,
|
||||
knowledge_base=character.knowledge_base,
|
||||
)
|
||||
|
||||
success = await hermes_client.create_profile(character.hermes_profile, soul_content)
|
||||
if success:
|
||||
character.soul_md = soul_content
|
||||
return success
|
||||
|
||||
async def create_all_profiles(self, session: AsyncSession, script_id: str) -> int:
|
||||
result = await session.execute(
|
||||
select(Character).where(Character.script_id == script_id)
|
||||
)
|
||||
characters = list(result.scalars().all())
|
||||
created = 0
|
||||
|
||||
for character in characters:
|
||||
try:
|
||||
if await self.create_profile(character):
|
||||
created += 1
|
||||
character.soul_md = soul_generator.generate(
|
||||
name=character.name,
|
||||
personality=character.personality,
|
||||
speaking_style=character.speaking_style,
|
||||
background=character.background,
|
||||
secret=character.secret,
|
||||
motive=character.motive,
|
||||
knowledge_base=character.knowledge_base,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to create profile for {character.name}: {e}")
|
||||
|
||||
await session.commit()
|
||||
logger.info(f"Created {created}/{len(characters)} profiles for script {script_id}")
|
||||
return created
|
||||
|
||||
async def delete_profile(self, character: Character) -> bool:
|
||||
return await hermes_client.delete_profile(character.hermes_profile)
|
||||
|
||||
|
||||
character_generator = CharacterGenerator()
|
||||
Reference in New Issue
Block a user