Commit Graph

12 Commits

Author SHA1 Message Date
tiennm99 3ac06bffaa feat(loldle): add ability and splash champion-guessing modules
Closes deferred phases 04 + 05 of loldle-new-modes plan.

- loldle-ability: 5 guesses, DDragon ability icon as photo. State pins
  slot (P/Q/W/E/R) so the same icon shows every turn. Abilities pulled
  from DDragon per-champion — same source loldle.net uses at runtime.
- loldle-splash: 4 guesses, random skin splash as photo. Skin pool
  scraped from loldle.net bundle (var Ad=[…] — 172 champs × 1939 skins,
  non-chroma, matches their splash mode exactly). URLs from Riot
  DDragon CDN (no version segment, stable across patches).
- fetch-ddragon-data.js: extended to write all four JSONs in one run.
  Shares a single DDragon per-champion fetch cycle (concurrency 10).
- Credits loldle.net + Riot Games in all loldle-family READMEs.

19 new tests (503 total). Lint clean. register:dry reports 12 loldle_*
commands with no conflicts.
2026-04-24 23:58:42 +07:00
tiennm99 bd5626534b feat(loldle): add emoji and quote champion-guessing modules
Ship two new loldle-family modules mirroring loldle.net's non-classic
modes. Text-only MVP (ability/splash phases stay deferred).

- loldle-emoji: 5 guesses, emoji-sequence clue. Pool derived algorithmically
  from classic's champions.json metadata (species/region/resource mapping
  table) since loldle.net's bundle has no static emoji pool.
- loldle-quote: 6 guesses, lore-blurb clue. Pool seeded from Data Dragon
  champion title + first lore sentence; champion name redacted to ___.
- scripts/fetch-ddragon-data.js: single generator for both JSONs.
- src/util/normalize-name.js: shared lookup helper; loldle/lookup.js
  refactored to import it.

35 new tests (484 total passing). Lint clean.
2026-04-24 23:30:11 +07:00
tiennm99 8b8eb16911 docs(plans): archive code-review audit report from twentyq plan
Output of the code-reviewer subagent run that drove commit 3be799d.
Kept under the plan dir so the cleanup decisions stay traceable.
2026-04-24 18:58:12 +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
tiennm99 fd5a1d2903 feat(semantle,doantu): calibrate cosine score via normalized sigmoid
BGE embeddings occupy a narrow cone in vector space, so raw cosine of
two unrelated words already sits at ~0.40-0.55. Displaying `raw * 100`
made every random guess read as 40-70% warm, which defeated the warmth
UX.

format.js now applies a normalized sigmoid (FLOOR 0.40, CENTER 0.60,
SCALE 8) to remap raw cosine → displayed 0-100. Unrelated pairs drop
to ≤30, loose relation lands around 40-55, clear synonyms hit 85+, and
exact match stays at 100. Emoji buckets were rebased onto the calibrated
score; formatWarmth lost its sign column (calibrated output is always
non-negative).

render.js rounds once and feeds the integer to both formatWarmth and
warmthEmoji so the display value and bucket stay in sync.

Constants are empirical — retune if swapping to a non-BGE model.
2026-04-23 00:33:54 +07:00
tiennm99 31ced88b78 refactor(semantle): swap ConceptNet for Workers AI embeddings
ConceptNet (api.conceptnet.io) was returning sustained 502s, breaking
every guess with an "Upstream hiccup" reply. Replace with env.AI.run
on @cf/baai/bge-small-en-v1.5 and score guesses by computing cosine
similarity locally against the target vector.

The local google-10k wordlist doubles as the in/out-of-vocabulary set,
so OOV detection is an O(1) Set.has() with no upstream call. The
similarity() response shape is unchanged, so handlers/render/state
stay as-is.

Free on the Workers Free plan: 10k Neurons/day cap, ~0.0037 Neurons
per 2-word guess → ~2.7M guesses/day headroom for this bot.
2026-04-22 23:48:17 +07:00
tiennm99 08ff72985a feat(semantle): add word2vec guessing game module
Telegram commands /semantle, /semantle_new, /semantle_giveup, /semantle_stats.
Round starts with /random pick from hosted word2sim; each guess scored via
/similarity. Unlimited guesses; solve on case-insensitive exact match.

New env var WORD2SIM_API_URL (wrangler.toml, .env.deploy). Includes
module README and 90 unit tests covering api-client, state, format,
render, and handlers.
2026-04-22 22:05:27 +07:00
tiennm99 57c6528af7 docs(plans): add Leaguepedia API verification reports
Captures the feasibility check and auth-token investigation that led to
the lolschedule module: confirmed endpoint + table + field set, and
documented why caching beats token-based rate-limit mitigation on Fandom.
2026-04-21 09:36:39 +07:00
tiennm99 129a4cfd7d chore: remove completed plans and reports 2026-04-15 13:30:44 +07:00
tiennm99 6a4829e45b chore: add plan and phase reports for D1 + cron rollout 2026-04-15 13:29:48 +07:00
tiennm99 c9270764f2 feat: add fake trading module with crypto, stocks, forex and gold
Paper trading system with 5 commands (trade_topup, trade_buy,
trade_sell, trade_convert, trade_stats). Supports VN stocks via TCBS,
crypto via CoinGecko, forex via ER-API, and gold via PAX Gold proxy.
Per-user portfolio stored in KV with 60s price caching. 54 new tests.
2026-04-14 15:16:53 +07:00
tiennm99 c4314f21df feat: scaffold plug-n-play telegram bot on cloudflare workers
grammY-based bot with a module plugin system loaded from the MODULES env
var. Three command visibility levels (public/protected/private) share a
unified command namespace with conflict detection at registry build.

- 4 initial modules (util, wordle, loldle, misc); util fully implemented,
  others are stubs proving the plugin system end-to-end
- util: /info (chat/thread/sender ids) + /help (pure renderer over the
  registry, HTML parse mode, escapes user-influenced strings)
- KVStore interface with CFKVStore and a per-module prefixing factory;
  getJSON/putJSON convenience helpers; other backends drop in via one file
- Webhook at POST /webhook with secret-token validation via grammY's
  webhookCallback; no admin HTTP surface
- Post-deploy register script (npm run deploy = wrangler deploy && node
  --env-file=.env.deploy scripts/register.js) for setWebhook and
  setMyCommands; --dry-run flag for preview
- 56 vitest unit tests across 7 suites covering registry, db wrapper,
  dispatcher, help renderer, validators, and HTML escaper
- biome for lint + format; phased implementation plan under plans/
2026-04-11 09:49:06 +07:00