fix: 20q now answers any question, not just yes/no
Allow open-ended questions like "What color is it?" or "How big is it?" The model now gives brief descriptive answers (capped at 12 words) for open questions while still answering Yes/No/Sometimes/Partly for binary ones. Updated command descriptions and in-game prompts accordingly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+12
-11
@@ -2772,9 +2772,10 @@ async def _generate_20q_thing() -> dict | None:
|
|||||||
async def _answer_20q(thing: str, category: str, question: str) -> str:
|
async def _answer_20q(thing: str, category: str, question: str) -> str:
|
||||||
system_msg = (
|
system_msg = (
|
||||||
f'You are playing 20 questions. You are thinking of: "{thing}" ({category}). '
|
f'You are playing 20 questions. You are thinking of: "{thing}" ({category}). '
|
||||||
"Answer the player's question with ONLY: Yes, No, Sometimes, or Partly. "
|
"Answer the player's question honestly and helpfully. "
|
||||||
"Do NOT reveal what you are thinking of. Do NOT give hints beyond the single word answer. "
|
"For yes/no questions: answer Yes, No, Sometimes, or Partly. "
|
||||||
"One word answer only."
|
"For open questions (color, size, shape, etc.): give a brief, accurate answer in 1-8 words. "
|
||||||
|
"CRITICAL: Do NOT say the name of the thing. Do NOT give it away. Keep answers short."
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
timeout = aiohttp.ClientTimeout(total=20)
|
timeout = aiohttp.ClientTimeout(total=20)
|
||||||
@@ -2787,15 +2788,15 @@ async def _answer_20q(thing: str, category: str, question: str) -> str:
|
|||||||
) as response:
|
) as response:
|
||||||
data = await response.json()
|
data = await response.json()
|
||||||
raw = data.get("message", {}).get("content", "").strip()
|
raw = data.get("message", {}).get("content", "").strip()
|
||||||
# Only keep the first word to prevent leakage
|
# Cap at 12 words to prevent the model rambling and leaking the answer
|
||||||
first_word = raw.split()[0].rstrip(".,!?") if raw.split() else "..."
|
words = raw.split()
|
||||||
return first_word
|
return " ".join(words[:12]) if words else "..."
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("20q answer error: %s", e, exc_info=True)
|
logger.error("20q answer error: %s", e, exc_info=True)
|
||||||
return "..."
|
return "..."
|
||||||
|
|
||||||
|
|
||||||
@command("20q", "AI thinks of something — ask up to 20 yes/no questions with !q, guess with !answer")
|
@command("20q", "AI thinks of something — ask up to 20 questions with !q, guess with !answer")
|
||||||
async def cmd_20q(client: AsyncClient, room_id: str, sender: str, args: str):
|
async def cmd_20q(client: AsyncClient, room_id: str, sender: str, args: str):
|
||||||
if room_id in _TWENTYQ_GAMES:
|
if room_id in _TWENTYQ_GAMES:
|
||||||
g = _TWENTYQ_GAMES[room_id]
|
g = _TWENTYQ_GAMES[room_id]
|
||||||
@@ -2819,14 +2820,14 @@ async def cmd_20q(client: AsyncClient, room_id: str, sender: str, args: str):
|
|||||||
"asked": [],
|
"asked": [],
|
||||||
}
|
}
|
||||||
await send_html(client, room_id,
|
await send_html(client, room_id,
|
||||||
f"🤔 I've got something in mind! Hint: {thing_data['hint']}\nAsk yes/no questions with !q <question> (20 total) or guess with !answer <guess>",
|
f"🤔 I've got something in mind! Hint: {thing_data['hint']}\nAsk any question with !q <question> (20 total) or guess with !answer <guess>",
|
||||||
f'<font color="#a855f7"><strong>🤔 20 Questions!</strong></font><br>'
|
f'<font color="#a855f7"><strong>🤔 20 Questions!</strong></font><br>'
|
||||||
f'I\'m thinking of something — hint: <em>{thing_data["hint"]}</em><br>'
|
f'I\'m thinking of something — hint: <em>{thing_data["hint"]}</em><br>'
|
||||||
f'Ask with <code>!q <question></code> (20 total) or guess with <code>!answer <guess></code>',
|
f'Ask anything with <code>!q <question></code> (20 total) or guess with <code>!answer <guess></code>',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@command("q", "Ask a yes/no question in 20 Questions (!q <question>)")
|
@command("q", "Ask a question in 20 Questions (!q <question>)")
|
||||||
async def cmd_q(client: AsyncClient, room_id: str, sender: str, args: str):
|
async def cmd_q(client: AsyncClient, room_id: str, sender: str, args: str):
|
||||||
if room_id not in _TWENTYQ_GAMES:
|
if room_id not in _TWENTYQ_GAMES:
|
||||||
await send_text(client, room_id, "No 20Q game active. Start one with !20q")
|
await send_text(client, room_id, "No 20Q game active. Start one with !20q")
|
||||||
@@ -2834,7 +2835,7 @@ async def cmd_q(client: AsyncClient, room_id: str, sender: str, args: str):
|
|||||||
g = _TWENTYQ_GAMES[room_id]
|
g = _TWENTYQ_GAMES[room_id]
|
||||||
question = sanitize_input(args.strip())
|
question = sanitize_input(args.strip())
|
||||||
if not question:
|
if not question:
|
||||||
await send_text(client, room_id, "Ask a question, e.g. !q Is it alive?")
|
await send_text(client, room_id, "Ask a question, e.g. !q Is it alive? or !q What color is it?")
|
||||||
return
|
return
|
||||||
if g["questions_left"] <= 0:
|
if g["questions_left"] <= 0:
|
||||||
await send_text(client, room_id, "No questions left! Use !answer to make your final guess.")
|
await send_text(client, room_id, "No questions left! Use !answer to make your final guess.")
|
||||||
|
|||||||
Reference in New Issue
Block a user