Commit Graph

3 Commits

Author SHA1 Message Date
tiennm99 f6ab94ffb0 feat(twentyq): LLM-generated category + initial hint from bare keyword seeds
Previously seeds carried hand-curated {category, target, initialHint}.
Now SEEDS is a flat string[] of keywords — at round-start, the model
generates {category, initialHint} on the fly. Benefits:
- adding a seed is trivial (just append a word)
- every round gets a fresh cryptic opener (varies across plays of the
  same word)
- HINT STYLE rules apply to the opening hint too, so the initial clue
  isn't a definitional giveaway

Implementation:
- prompts.buildStartRoundPrompt(target) — with good/bad examples
- ai-client.generateRoundStart(env, target) — same JSON-in-content
  approach as judge(), with defensive fallbacks + redactSecret
- handlers.startFreshGame now async; surfaces roundstart errors via the
  existing UPSTREAM_FAIL path

Tests: 449 pass (5 new for generateRoundStart, 1 for roundstart error path).
2026-04-24 16:26:55 +07:00
tiennm99 0887a07367 fix(twentyq): drop function calling, use JSON-in-content for Gemma 4 compat
Gemma 4 likely rejects the flat "traditional" tools schema we were sending
(the docs use OpenAI-wrapped shape for this model) — causing env.AI.run to
throw and users to see the "AI service hiccup" reply every turn.

Switch to the universal approach:
- system prompt asks the model for a one-line JSON {is_guess, answer, hint}
- ai-client.extractText handles both Workers-AI and OpenAI response shapes
- parseJudgementJson walks brace-depth to extract JSON from stray prose /
  accidental code fences
- logs twentyq_ai_throw / twentyq_ai_unparseable with preview on failure
  so future issues surface in wrangler tail immediately

Tests: 7 new (parser + extractText); 444 total pass.
2026-04-24 14:57:58 +07:00
tiennm99 5b12650906 feat(twentyq): add reverse-Akinator yes/no game module powered by Workers AI
- seeded 54 objects across 6 categories (instrument, animal, food, vehicle, sport, household)
- @cf/google/gemma-4-26b-a4b-it judges via function calling; returns {is_guess, answer, hint}
- pre-AI validator rejects open-ended questions; handler dedups exact repeats
- secret-redacting hint filter as defense-in-depth
- 86 new vitest tests (seeds, state, validator, ai-client, handlers, render)
2026-04-24 14:37:23 +07:00