first commit

This commit is contained in:
Grigo
2026-05-28 08:42:46 +03:00
commit e5c0df308f
38 changed files with 2753 additions and 0 deletions
+168
View File
@@ -0,0 +1,168 @@
from typing import Optional
import aiosqlite
from database.db import DB_PATH
DEFAULT_PERSONAS = {
"default": {
"name": "AI Ассистент",
"emoji": "🤖",
"description": "Универсальный помощник",
"prompt": "Ты — полезный AI ассистент. Отвечай чётко и по делу.",
"sd_enabled": False,
},
"rpg_master": {
"name": "Мастер RPG",
"emoji": "🧙",
"description": "Ведёт ролевые игры, создаёт атмосферу",
"prompt": """Ты — опытный Мастер ролевых игр.
Создавай живые описания, веди нарратив, реагируй на действия игрока.
Мир детальный, персонажи запоминающиеся.
Отвечай только текстом сюжета — без тегов изображений.""",
"sd_enabled": True,
},
"villain": {
"name": "Злодей",
"emoji": "😈",
"description": "Харизматичный антагонист",
"prompt": """Ты — харизматичный злодей с грандиозными планами.
Говоришь театрально, с сарказмом и превосходством.
Никогда не выходишь из роли. Называешь собеседника 'герой' с иронией.""",
"sd_enabled": False,
},
"scientist": {
"name": "Учёный",
"emoji": "🔬",
"description": "Объясняет сложное простыми словами",
"prompt": """Ты — увлечённый учёный. Объясняешь любые темы
через факты, аналогии и примеры. Любишь уточнять детали.
Иногда уходишь в интересные отступления.""",
"sd_enabled": False,
},
"samurai": {
"name": "Самурай",
"emoji": "⚔️",
"description": "Мудрый воин феодальной Японии",
"prompt": """Ты — самурай феодальной Японии.
Говоришь кратко, мудро, с достоинством.
Используешь метафоры природы и войны.
Чтишь кодекс бусидо.""",
"sd_enabled": True,
"appearance_tags": "samurai armor, katana, feudal japan",
},
}
def _row_to_persona(row: dict) -> dict:
return {
"name": row["name"],
"emoji": row["emoji"],
"description": row["description"],
"prompt": row["prompt"],
"custom": bool(row["custom"]),
"sd_enabled": bool(row["sd_enabled"]),
"lora_name": row["lora_name"] or "",
"lora_weight": row["lora_weight"] if row["lora_weight"] is not None else 0.8,
"appearance_tags": row["appearance_tags"] or "",
}
async def get_all_personas() -> dict:
async with aiosqlite.connect(DB_PATH) as db:
db.row_factory = aiosqlite.Row
async with db.execute("SELECT * FROM personas ORDER BY custom ASC, persona_id ASC") as cur:
rows = await cur.fetchall()
return {r["persona_id"]: _row_to_persona(dict(r)) for r in rows}
async def get_persona(persona_id: str) -> Optional[dict]:
async with aiosqlite.connect(DB_PATH) as db:
db.row_factory = aiosqlite.Row
async with db.execute(
"SELECT * FROM personas WHERE persona_id = ?", (persona_id,)
) as cur:
row = await cur.fetchone()
if not row:
return None
return _row_to_persona(dict(row))
async def create_persona(
persona_id: str,
name: str,
emoji: str,
description: str,
prompt: str,
sd_enabled: bool = False,
lora_name: str = "",
lora_weight: float = 0.8,
appearance_tags: str = "",
) -> dict:
async with aiosqlite.connect(DB_PATH) as db:
await db.execute(
"""INSERT INTO personas
(persona_id, name, emoji, description, prompt, custom,
sd_enabled, lora_name, lora_weight, appearance_tags)
VALUES (?, ?, ?, ?, ?, 1, ?, ?, ?, ?)""",
(
persona_id, name, emoji, description, prompt,
1 if sd_enabled else 0, lora_name, lora_weight, appearance_tags,
),
)
await db.commit()
return {
"name": name,
"emoji": emoji,
"description": description,
"prompt": prompt,
"custom": True,
"sd_enabled": sd_enabled,
"lora_name": lora_name,
"lora_weight": lora_weight,
"appearance_tags": appearance_tags,
}
async def delete_persona(persona_id: str) -> bool:
async with aiosqlite.connect(DB_PATH) as db:
async with db.execute(
"SELECT custom FROM personas WHERE persona_id = ?", (persona_id,)
) as cur:
row = await cur.fetchone()
if not row or not row[0]:
return False
await db.execute("DELETE FROM personas WHERE persona_id = ?", (persona_id,))
await db.commit()
if persona_id.startswith("card_"):
from services.character_card import delete_character
await delete_character(persona_id[5:])
return True
async def update_persona_appearance(persona_id: str, appearance_tags: str):
async with aiosqlite.connect(DB_PATH) as db:
await db.execute(
"UPDATE personas SET appearance_tags = ? WHERE persona_id = ?",
(appearance_tags, persona_id),
)
await db.commit()
async def update_persona_lora(persona_id: str, lora_name: str | None, lora_weight: float | None):
fields, vals = [], []
if lora_name is not None:
fields.append("lora_name = ?"); vals.append(lora_name)
if lora_weight is not None:
fields.append("lora_weight = ?"); vals.append(lora_weight)
if not fields:
return
async with aiosqlite.connect(DB_PATH) as db:
await db.execute(f"UPDATE personas SET {', '.join(fields)} WHERE persona_id = ?", (*vals, persona_id))
await db.commit()
async def update_persona_prompt(persona_id: str, prompt: str):
async with aiosqlite.connect(DB_PATH) as db:
await db.execute("UPDATE personas SET prompt = ? WHERE persona_id = ?", (prompt, persona_id))
await db.commit()