Added RPG
This commit is contained in:
+95
-4
@@ -63,9 +63,29 @@ def _row_to_persona(row: dict) -> dict:
|
||||
"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 "",
|
||||
"personality": row.get("personality", "") or "",
|
||||
"scenario": row.get("scenario", "") or "",
|
||||
"first_mes": row.get("first_mes", "") or "",
|
||||
"mes_example": row.get("mes_example", "") or "",
|
||||
"lorebook_json": row.get("lorebook_json", "[]") or "[]",
|
||||
"avatar_path": row.get("avatar_path", "") or "",
|
||||
}
|
||||
|
||||
|
||||
def build_persona_prompt(data: dict) -> str:
|
||||
parts = [
|
||||
f"You are {data.get('name', '').strip()}." if data.get("name") else "",
|
||||
f"Description: {data.get('description', '').strip()}",
|
||||
f"Personality: {data.get('personality', '').strip()}",
|
||||
f"Scenario: {data.get('scenario', '').strip()}",
|
||||
]
|
||||
ex = (data.get("mes_example") or "").strip()
|
||||
if ex:
|
||||
parts.append(f"Example dialogue:\n{ex}")
|
||||
parts.append("Stay in character. Reply as the character. Do not add image tags.")
|
||||
return "\n\n".join(p for p in parts if p and p.split(": ", 1)[-1].strip())
|
||||
|
||||
|
||||
async def get_all_personas() -> dict:
|
||||
async with aiosqlite.connect(DB_PATH) as db:
|
||||
db.row_factory = aiosqlite.Row
|
||||
@@ -96,16 +116,33 @@ async def create_persona(
|
||||
lora_name: str = "",
|
||||
lora_weight: float = 0.8,
|
||||
appearance_tags: str = "",
|
||||
personality: str = "",
|
||||
scenario: str = "",
|
||||
first_mes: str = "",
|
||||
mes_example: str = "",
|
||||
lorebook_json: str = "[]",
|
||||
avatar_path: str = "",
|
||||
) -> dict:
|
||||
final_prompt = prompt.strip() or build_persona_prompt(
|
||||
{
|
||||
"name": name,
|
||||
"description": description,
|
||||
"personality": personality,
|
||||
"scenario": scenario,
|
||||
"mes_example": mes_example,
|
||||
}
|
||||
)
|
||||
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, ?, ?, ?, ?)""",
|
||||
sd_enabled, lora_name, lora_weight, appearance_tags,
|
||||
personality, scenario, first_mes, mes_example, lorebook_json, avatar_path)
|
||||
VALUES (?, ?, ?, ?, ?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
|
||||
(
|
||||
persona_id, name, emoji, description, prompt,
|
||||
persona_id, name, emoji, description, final_prompt,
|
||||
1 if sd_enabled else 0, lora_name, lora_weight, appearance_tags,
|
||||
personality, scenario, first_mes, mes_example, lorebook_json, avatar_path,
|
||||
),
|
||||
)
|
||||
await db.commit()
|
||||
@@ -113,12 +150,18 @@ async def create_persona(
|
||||
"name": name,
|
||||
"emoji": emoji,
|
||||
"description": description,
|
||||
"prompt": prompt,
|
||||
"prompt": final_prompt,
|
||||
"custom": True,
|
||||
"sd_enabled": sd_enabled,
|
||||
"lora_name": lora_name,
|
||||
"lora_weight": lora_weight,
|
||||
"appearance_tags": appearance_tags,
|
||||
"personality": personality,
|
||||
"scenario": scenario,
|
||||
"first_mes": first_mes,
|
||||
"mes_example": mes_example,
|
||||
"lorebook_json": lorebook_json,
|
||||
"avatar_path": avatar_path,
|
||||
}
|
||||
|
||||
|
||||
@@ -166,3 +209,51 @@ 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()
|
||||
|
||||
|
||||
async def patch_persona(persona_id: str, fields: dict) -> bool:
|
||||
allowed = {
|
||||
"name",
|
||||
"emoji",
|
||||
"description",
|
||||
"prompt",
|
||||
"sd_enabled",
|
||||
"lora_name",
|
||||
"lora_weight",
|
||||
"appearance_tags",
|
||||
"personality",
|
||||
"scenario",
|
||||
"first_mes",
|
||||
"mes_example",
|
||||
"lorebook_json",
|
||||
"avatar_path",
|
||||
}
|
||||
updates = {k: v for k, v in fields.items() if k in allowed}
|
||||
if not updates:
|
||||
return False
|
||||
|
||||
async with aiosqlite.connect(DB_PATH) as db:
|
||||
db.row_factory = aiosqlite.Row
|
||||
# disallow editing built-in personas
|
||||
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
|
||||
|
||||
# rebuild prompt if user didn't explicitly set it
|
||||
raw_fields = {"name", "description", "personality", "scenario", "mes_example"}
|
||||
if "prompt" not in updates and (raw_fields & updates.keys()):
|
||||
async with db.execute("SELECT * FROM personas WHERE persona_id = ?", (persona_id,)) as cur:
|
||||
existing = await cur.fetchone()
|
||||
if existing:
|
||||
merged = dict(existing)
|
||||
merged.update(updates)
|
||||
updates["prompt"] = build_persona_prompt(merged)
|
||||
|
||||
cols = ", ".join(f"{k} = ?" for k in updates)
|
||||
cur2 = await db.execute(
|
||||
f"UPDATE personas SET {cols} WHERE persona_id = ?",
|
||||
(*updates.values(), persona_id),
|
||||
)
|
||||
await db.commit()
|
||||
return cur2.rowcount > 0
|
||||
|
||||
Reference in New Issue
Block a user