From bc84507e644a8a06bcaabca30c830db7f6a564fa Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Wed, 22 Apr 2026 21:23:01 -0400 Subject: [PATCH] wyr: few-shot examples + rebuild question from options + switch to abliterated model - Add 3 assistant-turn examples to lock in the JSON format and tone - Construct the 'question' field from option_a/option_b so it's always well-formed regardless of what the model puts in the 'question' key - Switch from phi4-mini to the abliterated Llama 3.2 model for edgier, uncensored dilemmas Co-Authored-By: Claude Sonnet 4.6 --- matrixbot/commands.py | 44 +++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/matrixbot/commands.py b/matrixbot/commands.py index cb31e50..2717ca8 100644 --- a/matrixbot/commands.py +++ b/matrixbot/commands.py @@ -1646,44 +1646,48 @@ def record_wyr_vote(event_id: str, sender: str, key: str) -> None: async def _generate_wyr() -> dict | None: + # Few-shot examples anchor the format so the model doesn't drift + examples = [ + ('{"question": "Would you rather...", "option_a": "have no internet for a year", "option_b": "never eat your favorite food again"}',), + ('{"question": "Would you rather...", "option_a": "always speak in rhymes", "option_b": "only communicate in interpretive dance"}',), + ('{"question": "Would you rather...", "option_a": "know the date you die", "option_b": "know the cause of your death"}',), + ] system_msg = ( - "You are a game host generating Would You Rather questions for a group of adult friends. " - "Always respond with ONLY a JSON object — no markdown fences, no explanation. " - 'Format: {"question": "Would you rather...", "option_a": "short option", "option_b": "short option"}\n' - "Make the dilemma genuinely difficult — both options should have real downsides so it's actually a hard choice. " - "Be creative and edgy: embarrassing scenarios, weird superpowers, social nightmares, gross but survivable situations, " - "impossible tradeoffs. Avoid boring safe options like 'dance with dolphins' or 'sing karaoke'. " - "Keep each option under 10 words." + "You are a game host generating Would You Rather dilemmas for a group of adult friends. " + "STRICT FORMAT — respond with ONLY a valid JSON object, no other text:\n" + '{"question": "Would you rather...", "option_a": "", "option_b": ""}\n\n' + "Rules:\n" + "- The 'question' field must ALWAYS be exactly the string 'Would you rather...'\n" + "- option_a and option_b are the two actual choices — complete, self-contained phrases\n" + "- Both options must have genuine downsides — make it a real dilemma, not an easy pick\n" + "- Be edgy and creative: social nightmares, cursed superpowers, embarrassing scenarios, impossible tradeoffs\n" + "- Do NOT generate scenarios (no 'accidentally swallow', no 'at midnight') — just two clean choices" ) - user_msg = "Generate a spicy, genuinely difficult Would You Rather question." + messages = [{"role": "system", "content": system_msg}] + for (ex,) in examples: + messages.append({"role": "assistant", "content": ex}) + messages.append({"role": "user", "content": "Generate a new spicy, genuinely difficult Would You Rather."}) + try: timeout = aiohttp.ClientTimeout(total=60) async with aiohttp.ClientSession(timeout=timeout) as session: async with session.post( f"{OLLAMA_URL}/api/chat", - json={ - "model": ASK_MODEL, - "stream": False, - "messages": [ - {"role": "system", "content": system_msg}, - {"role": "user", "content": user_msg}, - ], - }, + json={"model": BALL_MODEL, "stream": False, "messages": messages}, ) as response: data = await response.json() text = data.get("message", {}).get("content", "").strip() - # Strip markdown fences if present if "```" in text: text = re.sub(r"```[a-z]*\n?", "", text).strip() - # Extract the first JSON object found in the response m = re.search(r"\{[^{}]+\}", text, re.DOTALL) if m: text = m.group(0) parsed = json.loads(text) - q = parsed.get("question", "").strip() a = parsed.get("option_a", "").strip() b = parsed.get("option_b", "").strip() - if q and a and b: + # Rebuild question from options so it's always well-formed + if a and b: + q = f"Would you rather {a.rstrip('.')} OR {b.rstrip('.')}?" return {"question": q, "option_a": a, "option_b": b} except Exception as e: logger.error(f"WYR generation error: {e}", exc_info=True)