trivia: add 8 new categories + per-category dedup cache
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:
+34
-9
@@ -798,12 +798,20 @@ async def cmd_agent(client: AsyncClient, room_id: str, sender: str, args: str):
|
|||||||
|
|
||||||
|
|
||||||
_TRIVIA_CATEGORIES = {
|
_TRIVIA_CATEGORIES = {
|
||||||
"gaming": "video games, gaming history, game mechanics, esports",
|
"gaming": "video games, gaming history, game mechanics, esports, retro gaming, game franchises",
|
||||||
"tech": "technology, programming, computers, the internet, software",
|
"tech": "technology, programming, computers, the internet, software, hardware, open source, networking",
|
||||||
"general": "general knowledge, world facts, history, science, geography",
|
"general": "general knowledge, world facts, history, science, geography, politics, culture",
|
||||||
"movies": "movies, film history, actors, directors, pop culture",
|
"movies": "movies, film history, actors, directors, pop culture, Oscar winners, franchises",
|
||||||
"music": "music, bands, songs, music history, artists",
|
"music": "music, bands, songs, music history, artists, albums, genres",
|
||||||
"science": "science, biology, physics, chemistry, space",
|
"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 = [
|
_TRIVIA_FALLBACKS = [
|
||||||
@@ -830,12 +838,24 @@ _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:
|
async def _generate_trivia_question(category: str) -> dict | None:
|
||||||
"""Ask the LLM to generate a trivia question. Returns None on failure."""
|
"""Ask the LLM to generate a trivia question. Returns None on failure."""
|
||||||
topic = _TRIVIA_CATEGORIES.get(category, _TRIVIA_CATEGORIES["general"])
|
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 = (
|
prompt = (
|
||||||
f"Generate a trivia question about {topic}. "
|
f"Generate a trivia question about {topic}."
|
||||||
"Respond with ONLY a JSON object, no markdown, no explanation. "
|
+ 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} '
|
'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. "
|
"where answer is the 0-based index of the correct option. "
|
||||||
"The question should be clear, factual, and have exactly one correct answer."
|
"The question should be clear, factual, and have exactly one correct answer."
|
||||||
@@ -873,13 +893,18 @@ async def _generate_trivia_question(category: str) -> dict | None:
|
|||||||
and isinstance(parsed.get("answer"), int)
|
and isinstance(parsed.get("answer"), int)
|
||||||
and 0 <= parsed["answer"] <= 3
|
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
|
return parsed
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
return None
|
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):
|
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"
|
category = args.strip().lower() if args.strip().lower() in _TRIVIA_CATEGORIES else "general"
|
||||||
if args.strip() and args.strip().lower() not in _TRIVIA_CATEGORIES:
|
if args.strip() and args.strip().lower() not in _TRIVIA_CATEGORIES:
|
||||||
|
|||||||
Reference in New Issue
Block a user