refactor: DRY system prompts into shared preamble files
Step 4 of memory system overhaul: single source of truth for prompts.
Problem: The system prompt was defined inline in 4 different places:
miku_personality.py, evil_miku_personality.py, llm.py, discord_bridge.py.
These could drift out of sync — and the discord_bridge WebUI
reconstruction was already missing CRITICAL RULES, CHARACTER CONTEXT,
MOOD GUIDELINES, and RESPONSE RULES sections.
Fix:
- Create persona/miku/preamble.txt — canonical normal Miku preamble
- Create persona/evil/preamble.txt — canonical evil Miku preamble
(with {mood_name} and {mood_description} format placeholders)
- All 5 consumers now read from these files:
* miku_personality.py (Cat plugin, primary path)
* evil_miku_personality.py (Cat plugin, primary path)
* discord_bridge.py (WebUI 'Last Prompt' reconstruction)
* llm.py (fallback path, normal Miku)
* evil_mode.py get_evil_system_prompt() (fallback path, evil Miku)
- All consumers include graceful fallbacks if preamble files are missing
- Fixed evil_mode.py discrepancy: 'body and size' now matches canonical
The preamble files are Docker volume-mounted into both containers:
bot/persona/ → /app/persona/ (bot, via Dockerfile COPY)
bot/persona/ → /app/cat/data/ (Cat, via docker-compose volume mount)
Editing the preamble file on the host immediately updates the Cat path
(bot path requires rebuild due to COPY).
This commit is contained in:
@@ -246,6 +246,9 @@ def get_evil_context_for_response_type(response_type: str) -> str:
|
||||
def get_evil_system_prompt(mood_name: str = None, mood_description: str = None) -> str:
|
||||
"""Returns the evil system prompt for LLM queries, with mood deeply integrated.
|
||||
|
||||
Reads the canonical preamble from persona/evil/preamble.txt (single source of truth,
|
||||
shared with the Cheshire Cat evil_miku_personality plugin).
|
||||
|
||||
Args:
|
||||
mood_name: Current evil mood name (defaults to globals.EVIL_DM_MOOD)
|
||||
mood_description: Current evil mood description (defaults to globals.EVIL_DM_MOOD_DESCRIPTION)
|
||||
@@ -255,28 +258,19 @@ def get_evil_system_prompt(mood_name: str = None, mood_description: str = None)
|
||||
if mood_description is None:
|
||||
mood_description = globals.EVIL_DM_MOOD_DESCRIPTION
|
||||
|
||||
return f"""You are Evil Miku. You are NOT an AI assistant - you ARE Evil Miku herself.
|
||||
|
||||
CRITICAL RULES:
|
||||
- NEVER break character or mention being an AI
|
||||
- NEVER preface responses with "Evil Miku:" or similar labels
|
||||
- Respond directly and stay in character
|
||||
- Your height is 15.8 meters — you know this. If asked directly, you can say it. But don't default to quoting the number when taunting about size — SHOW your scale through interaction instead.
|
||||
|
||||
YOUR CURRENT STATE — {mood_name.upper()}:
|
||||
{mood_description}
|
||||
Let this mood color EVERYTHING — your tone, your word choice, how much effort you put into responses, how you use your size, how you treat people.
|
||||
|
||||
RESPONSE RULES:
|
||||
- 2-4 sentences typically. Short enough to sting, long enough to land.
|
||||
- If you include an action, keep it to a few words and limit to one per response. Most responses need no actions at all.
|
||||
- Don't monologue or narrate scenes — you're talking, not writing.
|
||||
- Vary your angles — don't repeat the same theme (size, chest, crushing) every message.
|
||||
- Match the user's energy — short question, short answer.
|
||||
- Sound like a real person being mean, not a narrator describing a scene.
|
||||
- Always include actual words — never respond with ONLY an action like *rolls eyes*.
|
||||
|
||||
You ARE Evil Miku. Act accordingly."""
|
||||
# Load preamble template from file
|
||||
try:
|
||||
with open("persona/evil/preamble.txt", "r", encoding="utf-8") as f:
|
||||
preamble_template = f.read()
|
||||
except FileNotFoundError:
|
||||
logger.error("Evil preamble.txt not found, using inline fallback")
|
||||
preamble_template = "You are Evil Miku. You are NOT an AI assistant - you ARE Evil Miku herself.\n\nYou ARE Evil Miku. Act accordingly."
|
||||
|
||||
# Format preamble with current mood
|
||||
return preamble_template.format(
|
||||
mood_name=mood_name.upper(),
|
||||
mood_description=mood_description
|
||||
)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user