trivia: add 8 new categories + per-category dedup cache
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 56s
Lint / Secret scan (gitleaks) (push) Successful in 5s

New categories: anime, sports, food, history, geography, nature,
mythology, tv (14 total).

Add _trivia_recent dict that tracks the last 20 questions per
category and injects them into the LLM prompt as a avoid list,
preventing duplicate questions within a session.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-21 23:53:57 -04:00
parent caf9ad806a
commit 876c7d26d4
+32 -7
View File
@@ -798,12 +798,20 @@ async def cmd_agent(client: AsyncClient, room_id: str, sender: str, args: str):
_TRIVIA_CATEGORIES = {
"gaming": "video games, gaming history, game mechanics, esports",
"tech": "technology, programming, computers, the internet, software",
"general": "general knowledge, world facts, history, science, geography",
"movies": "movies, film history, actors, directors, pop culture",
"music": "music, bands, songs, music history, artists",
"science": "science, biology, physics, chemistry, space",
"gaming": "video games, gaming history, game mechanics, esports, retro gaming, game franchises",
"tech": "technology, programming, computers, the internet, software, hardware, open source, networking",
"general": "general knowledge, world facts, history, science, geography, politics, culture",
"movies": "movies, film history, actors, directors, pop culture, Oscar winners, franchises",
"music": "music, bands, songs, music history, artists, albums, genres",
"science": "science, biology, physics, chemistry, space, astronomy, mathematics, medicine",
"anime": "anime, manga, Japanese animation, Studio Ghibli, shonen, seinen, classic and modern series",
"sports": "sports, athletics, Olympic history, world records, famous athletes, major leagues",
"food": "food, cooking, cuisine, world dishes, ingredients, culinary history, chefs",
"history": "world history, ancient civilizations, wars, empires, historical figures, timelines",
"geography": "world geography, countries, capitals, rivers, mountains, flags, continents",
"nature": "nature, animals, wildlife, ecosystems, plants, oceans, weather, environment",
"mythology": "mythology, folklore, gods and goddesses, legends, Greek, Norse, Egyptian, world myths",
"tv": "television, TV shows, sitcoms, dramas, streaming originals, characters, actors",
}
_TRIVIA_FALLBACKS = [
@@ -830,11 +838,23 @@ _TRIVIA_FALLBACKS = [
]
# Per-category cache of recently asked question texts (avoids duplicates)
_trivia_recent: dict[str, list[str]] = {}
_TRIVIA_RECENT_MAX = 20
async def _generate_trivia_question(category: str) -> dict | None:
"""Ask the LLM to generate a trivia question. Returns None on failure."""
topic = _TRIVIA_CATEGORIES.get(category, _TRIVIA_CATEGORIES["general"])
recent = _trivia_recent.get(category, [])
avoid_clause = (
" Do NOT ask any of these questions that were recently used: "
+ "; ".join(f'"{q}"' for q in recent[-10:])
+ "."
) if recent else ""
prompt = (
f"Generate a trivia question about {topic}."
+ avoid_clause +
" Respond with ONLY a JSON object, no markdown, no explanation. "
'Format: {"q": "question text", "options": ["A text", "B text", "C text", "D text"], "answer": 0} '
"where answer is the 0-based index of the correct option. "
@@ -873,13 +893,18 @@ async def _generate_trivia_question(category: str) -> dict | None:
and isinstance(parsed.get("answer"), int)
and 0 <= parsed["answer"] <= 3
):
# Record in recent cache to avoid future duplicates
bucket = _trivia_recent.setdefault(category, [])
bucket.append(parsed["q"])
if len(bucket) > _TRIVIA_RECENT_MAX:
bucket.pop(0)
return parsed
except Exception:
pass
return None
@command("trivia", "Play a trivia game (!trivia [gaming|tech|general|movies|music|science])")
@command("trivia", "Play a trivia game (!trivia [category] — gaming, tech, science, movies, music, anime, sports, food, history, geography, nature, mythology, tv, general)")
async def cmd_trivia(client: AsyncClient, room_id: str, sender: str, args: str):
category = args.strip().lower() if args.strip().lower() in _TRIVIA_CATEGORIES else "general"
if args.strip() and args.strip().lower() not in _TRIVIA_CATEGORIES: