Skip to content

feat: LLM-first definition system (GPT-5.2)#137

Merged
Hugo0 merged 1 commit intomainfrom
feat/llm-definition-system
Mar 4, 2026
Merged

feat: LLM-first definition system (GPT-5.2)#137
Hugo0 merged 1 commit intomainfrom
feat/llm-definition-system

Conversation

@Hugo0
Copy link
Owner

@Hugo0 Hugo0 commented Mar 4, 2026

Summary

Replaces the fragile 6-tier definition pipeline with a clean 3-tier system: disk cache → GPT-5.2 → kaikki (offline Wiktionary).

Why

  • Old parser picked wrong definitions for polysemous words ("greet" → "mourning" instead of "to welcome")
  • Wrong definitions cascaded to DALL-E images
  • 950 lines of regex parsing across 6 tiers with a 65-language confidence map was unmaintainable
  • LLM definitions are highest quality across all languages, and at 65 calls/day the cost is ~$0.15/day

What changed

  • New webapp/definitions.py (~310 lines) — GPT-5.2 structured JSON output with confidence scoring, dual definitions (native + English), disk caching, kaikki fallback
  • New scripts/pregenerate_definitions.py — daily cron pre-generates definitions so runtime never hits the LLM
  • Kaikki fallback — when LLM returns null (low confidence / unrecognized word), falls back to kaikki native → kaikki English. Covers ~60% of Dutch and ~52% of Romanian words where LLM struggles with rare vocabulary
  • DALL-E images now use definition_en (English) instead of native-language definitions
  • Frontend updated with new fields (definitionNative, definitionEn, confidence)
  • Old parser archived to webapp/deprecated/ and tests/deprecated/ (not deleted, recoverable)
  • Code quality — DRY kaikki lookups, removed unused strip_html/import re, kaikki results now include Wiktionary URLs
  • SEO improvements — updated meta descriptions for 55+ languages
  • Kaikki definition quality — sense-count selection improvements

Definition flow

1. Disk cache (pre-generated)
2. LLM (GPT-5.2) — structured JSON with confidence scoring
3. Kaikki native (offline, 13 major languages)
4. Kaikki English (offline, 50+ languages)
5. None → frontend hides card, word page has Wiktionary links

Testing

  • 2025 Python tests pass, 25 definition tests (5 for kaikki fallback), 81 frontend tests pass
  • Real LLM definitions verified across 18 words in 12+ languages including Klingon, Quenya, Palauan
  • Confidence threshold (0.3) prevents hallucination — Quenya correctly returns None

Post-merge TODOs

  • Run scripts/pregenerate_definitions.py --backfill 30 to populate cache for past daily words
  • Set up daily cron: definitions before images
  • Clear stale DALL-E images for words with wrong definitions

Test plan

  • All existing Python tests pass (2025 passed, 289 skipped, 4 xfailed)
  • All frontend tests pass (81 passed)
  • tests/test_definitions.py covers LLM parsing, cache behavior, kaikki fallback, backward compat
  • Real LLM testing across multiple languages and edge cases
  • Build succeeds (pnpm build)

@coderabbitai full review

…PT-5.2)

Replace the fragile 6-tier definition pipeline (plaintext parser → REST API →
kaikki native → kaikki English → LLM → disk cache) with a clean 2-tier system:
disk cache → GPT-5.2 structured JSON output.

Key changes:
- New webapp/definitions.py (~250 lines) replaces webapp/wiktionary.py (~950 lines)
- GPT-5.2 with structured JSON output returns definition_native + definition_en
- Confidence scoring (threshold 0.3) prevents hallucination
- DALL-E image generation now uses definition_en (fixes wrong images)
- Pre-generation script for daily cron (scripts/pregenerate_definitions.py)
- Old parser code archived to webapp/deprecated/ (not deleted)
- Tests moved to tests/deprecated/, new tests in tests/test_definitions.py
- Frontend updated with new definition fields (definitionNative, definitionEn)

Also includes: SEO description improvements for 55+ languages, kaikki definition
quality improvements (sense-count selection), and template updates.

Tested: 2025 Python tests pass, 81 frontend tests pass, real LLM definitions
verified across 18 words in 12+ languages including edge cases.
@coderabbitai
Copy link

coderabbitai bot commented Mar 4, 2026

Important

Review skipped

Too many files!

This PR contains 225 files, which is 75 over the limit of 150.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c6681b81-a453-40c3-a759-b039b732f393

📥 Commits

Reviewing files that changed from the base of the PR and between 3a3737e and fa12f29.

📒 Files selected for processing (225)
  • frontend/src/definitions.ts
  • frontend/src/types/index.ts
  • scripts/deprecated/build_definitions.py
  • scripts/deprecated/capture_wiktionary_fixtures.py
  • scripts/pregenerate_definitions.py
  • scripts/pregenerate_images.py
  • scripts/refresh_definition_cache.py
  • tests/conftest.py
  • tests/deprecated/__init__.py
  • tests/deprecated/fixtures/wiktionary/ar.json
  • tests/deprecated/fixtures/wiktionary/az.json
  • tests/deprecated/fixtures/wiktionary/bg.json
  • tests/deprecated/fixtures/wiktionary/br.json
  • tests/deprecated/fixtures/wiktionary/ca.json
  • tests/deprecated/fixtures/wiktionary/ckb.json
  • tests/deprecated/fixtures/wiktionary/cs.json
  • tests/deprecated/fixtures/wiktionary/da.json
  • tests/deprecated/fixtures/wiktionary/de.json
  • tests/deprecated/fixtures/wiktionary/el.json
  • tests/deprecated/fixtures/wiktionary/en.json
  • tests/deprecated/fixtures/wiktionary/eo.json
  • tests/deprecated/fixtures/wiktionary/es.json
  • tests/deprecated/fixtures/wiktionary/et.json
  • tests/deprecated/fixtures/wiktionary/eu.json
  • tests/deprecated/fixtures/wiktionary/fa.json
  • tests/deprecated/fixtures/wiktionary/fi.json
  • tests/deprecated/fixtures/wiktionary/fo.json
  • tests/deprecated/fixtures/wiktionary/fr.json
  • tests/deprecated/fixtures/wiktionary/fur.json
  • tests/deprecated/fixtures/wiktionary/fy.json
  • tests/deprecated/fixtures/wiktionary/ga.json
  • tests/deprecated/fixtures/wiktionary/gd.json
  • tests/deprecated/fixtures/wiktionary/gl.json
  • tests/deprecated/fixtures/wiktionary/he.json
  • tests/deprecated/fixtures/wiktionary/hr.json
  • tests/deprecated/fixtures/wiktionary/hu.json
  • tests/deprecated/fixtures/wiktionary/hy.json
  • tests/deprecated/fixtures/wiktionary/hyw.json
  • tests/deprecated/fixtures/wiktionary/ia.json
  • tests/deprecated/fixtures/wiktionary/ie.json
  • tests/deprecated/fixtures/wiktionary/is.json
  • tests/deprecated/fixtures/wiktionary/it.json
  • tests/deprecated/fixtures/wiktionary/ka.json
  • tests/deprecated/fixtures/wiktionary/ko.json
  • tests/deprecated/fixtures/wiktionary/la.json
  • tests/deprecated/fixtures/wiktionary/lb.json
  • tests/deprecated/fixtures/wiktionary/lt.json
  • tests/deprecated/fixtures/wiktionary/ltg.json
  • tests/deprecated/fixtures/wiktionary/lv.json
  • tests/deprecated/fixtures/wiktionary/mi.json
  • tests/deprecated/fixtures/wiktionary/mk.json
  • tests/deprecated/fixtures/wiktionary/mn.json
  • tests/deprecated/fixtures/wiktionary/nb.json
  • tests/deprecated/fixtures/wiktionary/nds.json
  • tests/deprecated/fixtures/wiktionary/ne.json
  • tests/deprecated/fixtures/wiktionary/nl.json
  • tests/deprecated/fixtures/wiktionary/nn.json
  • tests/deprecated/fixtures/wiktionary/oc.json
  • tests/deprecated/fixtures/wiktionary/pau.json
  • tests/deprecated/fixtures/wiktionary/pl.json
  • tests/deprecated/fixtures/wiktionary/pt.json
  • tests/deprecated/fixtures/wiktionary/qya.json
  • tests/deprecated/fixtures/wiktionary/ro.json
  • tests/deprecated/fixtures/wiktionary/ru.json
  • tests/deprecated/fixtures/wiktionary/rw.json
  • tests/deprecated/fixtures/wiktionary/sk.json
  • tests/deprecated/fixtures/wiktionary/sl.json
  • tests/deprecated/fixtures/wiktionary/sr.json
  • tests/deprecated/fixtures/wiktionary/sv.json
  • tests/deprecated/fixtures/wiktionary/tk.json
  • tests/deprecated/fixtures/wiktionary/tlh.json
  • tests/deprecated/fixtures/wiktionary/tr.json
  • tests/deprecated/fixtures/wiktionary/uk.json
  • tests/deprecated/fixtures/wiktionary/vi.json
  • tests/deprecated/test_wiktionary.py
  • tests/deprecated/test_wiktionary_definitions.py
  • tests/deprecated/test_wiktionary_parser.py
  • tests/deprecated/wiktionary_test_utils.py
  • tests/fixtures/wiktionary/az.json
  • tests/fixtures/wiktionary/ca.json
  • tests/fixtures/wiktionary/en.json
  • tests/fixtures/wiktionary/eo.json
  • tests/fixtures/wiktionary/es.json
  • tests/fixtures/wiktionary/gl.json
  • tests/fixtures/wiktionary/hr.json
  • tests/fixtures/wiktionary/is.json
  • tests/fixtures/wiktionary/it.json
  • tests/fixtures/wiktionary/nb.json
  • tests/fixtures/wiktionary/nl.json
  • tests/fixtures/wiktionary/oc.json
  • tests/fixtures/wiktionary/ro.json
  • tests/fixtures/wiktionary/tr.json
  • tests/test_definitions.py
  • webapp/app.py
  • webapp/data/definitions/ar_en.json
  • webapp/data/definitions/az_en.json
  • webapp/data/definitions/bg_en.json
  • webapp/data/definitions/br_en.json
  • webapp/data/definitions/ca_en.json
  • webapp/data/definitions/ckb_en.json
  • webapp/data/definitions/cs.json
  • webapp/data/definitions/cs_en.json
  • webapp/data/definitions/da_en.json
  • webapp/data/definitions/de.json
  • webapp/data/definitions/de_en.json
  • webapp/data/definitions/el.json
  • webapp/data/definitions/en.json
  • webapp/data/definitions/eo_en.json
  • webapp/data/definitions/es.json
  • webapp/data/definitions/es_en.json
  • webapp/data/definitions/et_en.json
  • webapp/data/definitions/eu_en.json
  • webapp/data/definitions/fa_en.json
  • webapp/data/definitions/fi_en.json
  • webapp/data/definitions/fo_en.json
  • webapp/data/definitions/fr.json
  • webapp/data/definitions/fur_en.json
  • webapp/data/definitions/fy_en.json
  • webapp/data/definitions/ga_en.json
  • webapp/data/definitions/gd_en.json
  • webapp/data/definitions/gl_en.json
  • webapp/data/definitions/he_en.json
  • webapp/data/definitions/hr_en.json
  • webapp/data/definitions/hu_en.json
  • webapp/data/definitions/hy_en.json
  • webapp/data/definitions/ia_en.json
  • webapp/data/definitions/is_en.json
  • webapp/data/definitions/it.json
  • webapp/data/definitions/it_en.json
  • webapp/data/definitions/ka_en.json
  • webapp/data/definitions/la_en.json
  • webapp/data/definitions/lb_en.json
  • webapp/data/definitions/lt_en.json
  • webapp/data/definitions/lv_en.json
  • webapp/data/definitions/mi_en.json
  • webapp/data/definitions/mk_en.json
  • webapp/data/definitions/mn_en.json
  • webapp/data/definitions/nb_en.json
  • webapp/data/definitions/nl.json
  • webapp/data/definitions/nn_en.json
  • webapp/data/definitions/oc_en.json
  • webapp/data/definitions/pl.json
  • webapp/data/definitions/pl_en.json
  • webapp/data/definitions/pt.json
  • webapp/data/definitions/pt_en.json
  • webapp/data/definitions/ro_en.json
  • webapp/data/definitions/ru.json
  • webapp/data/definitions/ru_en.json
  • webapp/data/definitions/sk_en.json
  • webapp/data/definitions/sl_en.json
  • webapp/data/definitions/sr_en.json
  • webapp/data/definitions/sv_en.json
  • webapp/data/definitions/tk_en.json
  • webapp/data/definitions/tr.json
  • webapp/data/definitions/tr_en.json
  • webapp/data/definitions/uk_en.json
  • webapp/data/definitions/vi.json
  • webapp/data/languages/ar/language_config.json
  • webapp/data/languages/az/language_config.json
  • webapp/data/languages/bg/language_config.json
  • webapp/data/languages/br/language_config.json
  • webapp/data/languages/ca/language_config.json
  • webapp/data/languages/ckb/language_config.json
  • webapp/data/languages/cs/language_config.json
  • webapp/data/languages/da/language_config.json
  • webapp/data/languages/el/language_config.json
  • webapp/data/languages/es/language_config.json
  • webapp/data/languages/et/language_config.json
  • webapp/data/languages/eu/language_config.json
  • webapp/data/languages/fa/language_config.json
  • webapp/data/languages/fi/language_config.json
  • webapp/data/languages/fo/language_config.json
  • webapp/data/languages/fr/language_config.json
  • webapp/data/languages/fur/language_config.json
  • webapp/data/languages/fy/language_config.json
  • webapp/data/languages/ga/language_config.json
  • webapp/data/languages/gl/language_config.json
  • webapp/data/languages/he/language_config.json
  • webapp/data/languages/hr/language_config.json
  • webapp/data/languages/hu/language_config.json
  • webapp/data/languages/hy/language_config.json
  • webapp/data/languages/hyw/language_config.json
  • webapp/data/languages/ia/language_config.json
  • webapp/data/languages/ie/language_config.json
  • webapp/data/languages/is/language_config.json
  • webapp/data/languages/it/language_config.json
  • webapp/data/languages/ka/language_config.json
  • webapp/data/languages/ko/language_config.json
  • webapp/data/languages/la/language_config.json
  • webapp/data/languages/lb/language_config.json
  • webapp/data/languages/lt/language_config.json
  • webapp/data/languages/ltg/language_config.json
  • webapp/data/languages/lv/language_config.json
  • webapp/data/languages/mi/language_config.json
  • webapp/data/languages/mk/language_config.json
  • webapp/data/languages/mn/language_config.json
  • webapp/data/languages/nb/language_config.json
  • webapp/data/languages/nds/language_config.json
  • webapp/data/languages/ne/language_config.json
  • webapp/data/languages/nl/language_config.json
  • webapp/data/languages/nn/language_config.json
  • webapp/data/languages/oc/language_config.json
  • webapp/data/languages/pau/language_config.json
  • webapp/data/languages/pt/language_config.json
  • webapp/data/languages/qya/language_config.json
  • webapp/data/languages/ro/language_config.json
  • webapp/data/languages/ru/language_config.json
  • webapp/data/languages/rw/language_config.json
  • webapp/data/languages/sk/language_config.json
  • webapp/data/languages/sl/language_config.json
  • webapp/data/languages/sr/language_config.json
  • webapp/data/languages/tk/language_config.json
  • webapp/data/languages/tlh/language_config.json
  • webapp/data/languages/tr/language_config.json
  • webapp/data/languages/uk/language_config.json
  • webapp/data/languages/vi/language_config.json
  • webapp/definitions.py
  • webapp/deprecated/__init__.py
  • webapp/deprecated/wiktionary_parser.py
  • webapp/templates/game.html
  • webapp/templates/index.html
  • webapp/templates/partials/_breadcrumb_schema.html
  • webapp/templates/word.html
  • webapp/templates/words_hub.html
  • webapp/wiktionary.py

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/llm-definition-system

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Hugo0 Hugo0 merged commit 909d9b4 into main Mar 4, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant