riddle: add dedup cache to prevent repeated riddles
Lint / Shell (shellcheck) (push) Successful in 10s
Lint / JS (eslint) (push) Successful in 7s
Lint / Python (ruff) (push) Successful in 5s
Lint / Python deps (pip-audit) (push) Successful in 43s
Lint / Secret scan (gitleaks) (push) Successful in 6s

Keep a rolling list of the last 30 riddles used and inject them into
the prompt as an avoid clause, same pattern as trivia's per-category cache.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-22 20:28:43 -04:00
parent 80d77a8a0f
commit 2457451d4c
+11 -1
View File
@@ -1762,14 +1762,21 @@ async def cmd_wyr(client: AsyncClient, room_id: str, sender: str, args: str):
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
_RIDDLE_ACTIVE: dict[str, dict] = {} _RIDDLE_ACTIVE: dict[str, dict] = {}
_riddle_recent: list[str] = []
_RIDDLE_RECENT_MAX = 30
async def _generate_riddle() -> dict | None: async def _generate_riddle() -> dict | None:
avoid_clause = (
" Do NOT use any of these riddles that were recently asked: "
+ "; ".join(f'"{r}"' for r in _riddle_recent[-15:])
+ "."
) if _riddle_recent else ""
system_msg = ( system_msg = (
"You are a riddle generator. Always respond with ONLY a JSON object — no markdown fences, no explanation. " "You are a riddle generator. Always respond with ONLY a JSON object — no markdown fences, no explanation. "
'Format: {"riddle": "the riddle text", "answer": "short answer"}' 'Format: {"riddle": "the riddle text", "answer": "short answer"}'
) )
user_msg = "Generate a clever riddle. The answer should be 1-4 words." user_msg = f"Generate a clever, original riddle. The answer should be 1-4 words.{avoid_clause}"
try: try:
timeout = aiohttp.ClientTimeout(total=60) timeout = aiohttp.ClientTimeout(total=60)
async with aiohttp.ClientSession(timeout=timeout) as session: async with aiohttp.ClientSession(timeout=timeout) as session:
@@ -1795,6 +1802,9 @@ async def _generate_riddle() -> dict | None:
riddle = parsed.get("riddle", "").strip() riddle = parsed.get("riddle", "").strip()
answer = parsed.get("answer", "").strip() answer = parsed.get("answer", "").strip()
if riddle and answer: if riddle and answer:
_riddle_recent.append(riddle)
if len(_riddle_recent) > _RIDDLE_RECENT_MAX:
_riddle_recent.pop(0)
return {"riddle": riddle, "answer": answer} return {"riddle": riddle, "answer": answer}
except Exception as e: except Exception as e:
logger.error(f"riddle generation error: {e}", exc_info=True) logger.error(f"riddle generation error: {e}", exc_info=True)