Fixed RPG

This commit is contained in:
2026-05-29 08:52:33 +03:00
parent e5c0df308f
commit 600ad78f05
24 changed files with 2804 additions and 144 deletions
+76
View File
@@ -0,0 +1,76 @@
import json
import os
from services.llm import send_message_with_model, send_message
FACTS_MODEL = os.getenv("RPG_FACTS_MODEL", "").strip() or "deepseek/deepseek-chat-v3"
FACTS_SYSTEM = """Extract stable facts from the conversation.
Return ONLY valid JSON (no markdown), as an array of short strings.
Rules:
- Facts must be durable (names, relations, inventory, locations, world rules).
- Do not include ephemeral actions unless they change state.
- Avoid duplicates.
- Keep each fact <= 120 chars.
Example output:
["User name is Alex", "We are in a ruined castle", "NPC Mira distrusts the user"]"""
def merge_facts(existing_json: str, new_facts: list[str], limit: int = 80) -> str:
try:
existing = json.loads(existing_json or "[]")
if not isinstance(existing, list):
existing = []
except json.JSONDecodeError:
existing = []
seen = {str(x).strip() for x in existing if str(x).strip()}
merged = [str(x).strip() for x in existing if str(x).strip()]
for f in new_facts:
s = str(f).strip()
if not s or s in seen:
continue
seen.add(s)
merged.append(s)
if len(merged) > limit:
merged = merged[-limit:]
return json.dumps(merged, ensure_ascii=False)
async def extract_facts(context_messages: list[dict]) -> list[str]:
# Build a compact transcript
transcript = "\n".join(
f"{m.get('role')}: {m.get('content','')}".strip()
for m in context_messages
if m.get("role") in ("user", "assistant")
)[-6000:]
messages = [
{"role": "system", "content": FACTS_SYSTEM},
{"role": "user", "content": transcript},
]
raw = await (send_message_with_model(messages, FACTS_MODEL) if FACTS_MODEL else send_message(messages))
try:
data = json.loads(raw.strip())
if isinstance(data, list):
return [str(x) for x in data][:40]
except Exception:
return []
return []
def facts_to_prompt(facts_json: str, max_items: int = 20) -> str:
try:
facts = json.loads(facts_json or "[]")
if not isinstance(facts, list):
return ""
except json.JSONDecodeError:
return ""
facts = [str(x).strip() for x in facts if str(x).strip()]
if not facts:
return ""
block = "\n".join(f"- {x}" for x in facts[-max_items:])
return f"--- Facts (persistent memory) ---\n{block}\n---"