import os
import spaces
import io
import base64
import json
import re
import random # Added for introducing randomness to the vocabulary generator
import numpy as np
import soundfile as sf
import torch
from PIL import Image
# 1. Apply transformers monkey patch to fix AutoAWQ compatibility
import transformers.activations
if not hasattr(transformers.activations, "PytorchGELUTanh"):
if hasattr(transformers.activations, "GELUTanh"):
transformers.activations.PytorchGELUTanh = transformers.activations.GELUTanh
else:
import torch.nn as nn
class PytorchGELUTanh(nn.Module):
def forward(self, x):
return nn.functional.gelu(x, approximate="tanh")
transformers.activations.PytorchGELUTanh = PytorchGELUTanh
from transformers import AutoModelForCausalLM, AutoTokenizer
from diffusers import SanaSprintPipeline
from qwen_tts import Qwen3TTSModel
from gradio import Server
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
# Initialize Server
app = Server()
# Create 'games' directory if it doesn't exist
os.makedirs("games", exist_ok=True)
# Mount the static 'games' directory so index.html can load JS files securely
app.mount("/games", StaticFiles(directory="games"), name="games")
# Model Initialization with try-except block
try:
# GGUF Configuration (using Qwen2.5-14B-Instruct GGUF as a stable reference)
# Ensure 'pip install gguf' is run in your environment.
llm_repo = "bartowski/Qwen2.5-14B-Instruct-GGUF"
gguf_filename = "Qwen2.5-14B-Instruct-Q4_0.gguf"
print(f"Loading GGUF LLM model {llm_repo} ({gguf_filename}) on GPU via transformers...")
tokenizer = AutoTokenizer.from_pretrained(llm_repo, gguf_file=gguf_filename)
llm_model = AutoModelForCausalLM.from_pretrained(
llm_repo,
gguf_file=gguf_filename,
torch_dtype=torch.bfloat16,
device_map="auto"
)
print("Loading Image model Sana Sprint 1.6B on GPU...")
sana_pipe = SanaSprintPipeline.from_pretrained(
"Efficient-Large-Model/Sana_Sprint_1.6B_1024px_diffusers",
torch_dtype=torch.bfloat16
)
sana_pipe.to("cuda:0")
print("Loading TTS model Qwen3-TTS 1.7B on GPU...")
# Apply flash-attention-3 optimization similar to Qwen3-TTS Hugging Face Space app.py
# Fall back safely to standard 'sdpa' or 'flash_attention_2' if kernels/drivers lack support
try:
tts_model = Qwen3TTSModel.from_pretrained(
"Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice",
device_map="cuda:0",
dtype=torch.bfloat16,
attn_implementation="kernels-community/flash-attn3",
)
print("Qwen3-TTS 1.7B loaded successfully with Flash Attention 3.")
except Exception as e_fa3:
print(f"Could not initialize Flash Attention 3 ({e_fa3}). Attempting SDPA fallback...")
try:
tts_model = Qwen3TTSModel.from_pretrained(
"Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice",
device_map="cuda:0",
dtype=torch.bfloat16,
attn_implementation="sdpa",
)
print("Qwen3-TTS 1.7B loaded successfully with SDPA fallback.")
except Exception as e_all:
# Absolute fallback in case of initialization exceptions
tts_model = Qwen3TTSModel.from_pretrained(
"Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice",
device_map="cuda:0",
dtype=torch.bfloat16,
)
print("Qwen3-TTS 1.7B loaded successfully with default attention.")
except Exception as e:
print(f"Error loading models on GPU during startup: {e}")
# Localization Database containing GUI texts, layout labels, and game translations
# Programmed with premium educational, context-rich terminology for serious language acquisition
# Includes a dynamically translatable "tutorial_text" for localized guidance
LOCALIZATION_DATABASE = {
"English": {
"title": "📘 WordConjure: Multimodal Vocabulary Practice",
"subtitle": "An educational system that automatically generates context-rich translations, clean pronunciation guides, and bespoke visual cards to optimize foreign language acquisition.",
"tutorial_text": "First: Select your target preferences below and click \"Generate Vocabulary\" to load your custom multimodal study deck. Then: Navigate to the \"Practice Exercises\" tab above to interactively test your memory through structured games.",
"settings": "⚙️ Session Configuration",
"word_count_label": "🔢 Vocabulary size to generate:",
"expl_lang_label": "🗣️ Explanation Language",
"app_lang_label": "📱 Application Language",
"source_lang": "🌍 Source Language (Native)",
"target_lang": "🎯 Target Language to Practice",
"btn_get_words": "⚡ Generate Vocabulary",
"tab_vocab": "📖 Vocabulary Deck",
"tab_games": "🎮 Practice Exercises",
"original_header": "Target Word",
"translation_header": "Translation",
"explanation_header": "Contextual Definition",
"visual_header": "Visual Card",
"audio_header": "Pronunciation",
"game_selection_title": "Select Your Practice Exercise",
"game_memory_title": "Interactive Memory Association",
"game_memory_desc": "Match target terms with their translated counterparts and generated visual cards to reinforce semantic retention.",
"game_monster_title": "Target Word Association (Word Monster)",
"game_monster_desc": "Select and present the appropriate translation card that accurately matches the requested target concept.",
"game_quiz_title": "Acoustic & Visual Assessment",
"game_quiz_desc": "Examine the audio pronunciation or visual cue and identify the correct matching term from multiple choices.",
"game_scramble_title": "Orthographic Word Reconstruction",
"game_scramble_desc": "Reassemble scrambled character sequences into the correct spelling of the translated target term.",
"game_linker_title": "Visual Term Correspondence Mapping",
"game_linker_desc": "Perform bilateral matching between generated visual cues and target practice words to solidify associations.",
"game_monster_feed_me": "PROVIDE THE CARD FOR:",
"game_monster_correct": "Correct translation identified! 🎉",
"game_monster_incorrect": "Incorrect card selected. 😢",
"game_monster_no_words": "Vocabulary list is empty!",
"game_monster_no_words_desc": "Please return to the 'Vocabulary Deck' tab, configure your target language, and select 'Generate Vocabulary' first.",
"game_quiz_hint_btn": "Hint 💡",
"game_quiz_replay_audio": "Play Audio 🔊",
"game_quiz_correct": "Correct! 🎉",
"game_quiz_incorrect": "Incorrect! Try again. 😢",
"game_quiz_question": "Identify this term:",
"game_quiz_need_four": "Please generate a minimum of 4 words to initialize the Acoustic & Visual Assessment.",
"game_scramble_clue_label": "Translate this term:",
"game_scramble_explanation_label": "Definition clue:",
"game_scramble_reset_btn": "Reset 🔄",
"game_scramble_play_audio": "Pronounce 🔊",
"game_scramble_correct": "Perfect Spelling! 🎉",
"game_scramble_incorrect": "Incorrect. Try again.",
"game_memory_moves": "Moves:",
"game_memory_congrats": "Success! All associations matched perfectly. 🎉",
"game_memory_need_words": "Please generate a minimum of 4 words to play Interactive Memory Association.",
"game_linker_instruction": "Select a visual card on the left, then map it to its corresponding practice word on the right.",
"game_linker_hint_btn": "Hint 💡",
"game_linker_correct": "Perfect Association! 🎉",
"game_linker_incorrect": "Mismatch! Try again. 😢",
"game_linker_select_clue": "Select a card on the left first to receive a context hint!",
"game_linker_need_words": "Please generate a minimum of 4 words to play Visual Term Correspondence Mapping."
},
"Spanish": {
"title": "📘 WordConjure: Práctica Multimodal de Vocabulario",
"subtitle": "Un sistema educativo que genera traducciones detalladas, guías de pronunciación claras y tarjetas visuales para optimizar el aprendizaje de idiomas.",
"tutorial_text": "Primero: Seleccione sus preferencias abajo y haga clic en \"Generar Vocabulario\" para cargar su mazo de estudio. Luego: Vaya a la pestaña \"Ejercicios de Práctica\" arriba para poner a prueba su memoria con juegos interactivos.",
"settings": "⚙️ Configuración de la sesión",
"word_count_label": "🔢 Cantidad de palabras a generar:",
"expl_lang_label": "🗣️ Idioma de la explicación",
"app_lang_label": "📱 Idioma de la aplicación",
"source_lang": "🌍 Idioma nativo (origen)",
"target_lang": "🎯 Idioma de práctica (destino)",
"btn_get_words": "⚡ Generar Vocabulario",
"tab_vocab": "📖 Mazo de Vocabulario",
"tab_games": "🎮 Ejercicios de Práctica",
"original_header": "Palabra Objetivo",
"translation_header": "Traducción",
"explanation_header": "Definición Contextual",
"visual_header": "Tarjeta Visual",
"audio_header": "Pronunciación",
"game_selection_title": "Seleccione el ejercicio de práctica",
"game_memory_title": "Asociación Interactiva de Memoria",
"game_memory_desc": "Asocie los términos con sus traducciones y tarjetas visuales para reforzar la retención semántica.",
"game_monster_title": "Asociación de Palabras (Monstruo de Palabras)",
"game_monster_desc": "Seleccione y presente la tarjeta de traducción que coincida exactamente con el concepto solicitado.",
"game_quiz_title": "Evaluación Acústica y Visual",
"game_quiz_desc": "Escuche la pronunciación o examine la pista visual e identifique el término correcto de opción múltiple.",
"game_scramble_title": "Reconstrucción Ortográfica de Palabras",
"game_scramble_desc": "Ordene la secuencia de caracteres para deletrear correctamente la traducción del término.",
"game_linker_title": "Mapeo de Correspondencia Visual",
"game_linker_desc": "Establezca correspondencias bilaterales entre imágenes de apoyo y palabras de práctica.",
"game_monster_feed_me": "PROPORCIONE LA TARJETA PARA:",
"game_monster_correct": "¡Traducción correcta identificada! 🎉",
"game_monster_incorrect": "Tarjeta incorrecta seleccionada. 😢",
"game_monster_no_words": "¡La lista de vocabulario está vacía!",
"game_monster_no_words_desc": "Regrese al 'Mazo de Vocabulario', configure el idioma de destino y presione 'Generar Vocabulario'.",
"game_quiz_hint_btn": "Pista 💡",
"game_quiz_replay_audio": "Reproducir Audio 🔊",
"game_quiz_correct": "¡Correcto! 🎉",
"game_quiz_incorrect": "¡Incorrecto! Inténtelo de nuevo. 😢",
"game_quiz_question": "Identifique este término:",
"game_quiz_need_four": "Genere un mínimo de 4 palabras para iniciar la Evaluación Acústica y Visual.",
"game_scramble_clue_label": "Traduzca este término:",
"game_scramble_explanation_label": "Pista de definición:",
"game_scramble_reset_btn": "Restablecer 🔄",
"game_scramble_play_audio": "Pronunciar 🔊",
"game_scramble_correct": "¡Ortografía perfecta! 🎉",
"game_scramble_incorrect": "Incorrecto. Inténtelo de nuevo.",
"game_memory_moves": "Movimientos:",
"game_memory_congrats": "¡Éxito! Todas las asociaciones se completaron perfectamente. 🎉",
"game_memory_need_words": "Genere un mínimo de 4 palabras para iniciar la Asociación Interactiva de Memoria.",
"game_linker_instruction": "Seleccione una tarjeta visual a la izquierda, luego asóciela con su palabra correspondiente a la derecha.",
"game_linker_hint_btn": "Pista 💡",
"game_linker_correct": "¡Asociación perfecta! 🎉",
"game_linker_incorrect": "¡No coincide! Inténtelo de nuevo. 😢",
"game_linker_select_clue": "¡Seleccione una tarjeta a la izquierda primero para obtener una pista!",
"game_linker_need_words": "Genere un mínimo de 4 palabras para jugar al Mapeo de Correspondencia Visual."
},
"French": {
"title": "📘 WordConjure : Pratique Multimodale du Vocabulaire",
"subtitle": "Une plateforme d'entraînement linguistique générant des définitions contextuelles, des cartes illustrées et des guides de prononciation clairs.",
"tutorial_text": "D'abord : Sélectionnez vos préférences ci-dessous et cliquez sur \"Générer le vocabulaire\" pour charger votre deck. Ensuite : Allez dans l'onglet \"Exercices d'entraînement\" ci-dessus pour tester votre mémoire avec des jeux interactifs.",
"settings": "⚙️ Configuration de la session",
"word_count_label": "🔢 Nombre de mots à générer :",
"expl_lang_label": "🗣️ Langue d'explication",
"app_lang_label": "📱 Langue de l'application",
"source_lang": "🌍 Langue maternelle",
"target_lang": "🎯 Langue à pratiquer",
"btn_get_words": "⚡ Générer le vocabulaire",
"tab_vocab": "📖 Deck de vocabulaire",
"tab_games": "🎮 Exercices d'entraînement",
"original_header": "Mot ciblé",
"translation_header": "Traduction",
"explanation_header": "Définition contextuelle",
"visual_header": "Carte visuelle",
"audio_header": "Prononciation",
"game_selection_title": "Sélectionnez l'exercice d'entraînement",
"game_memory_title": "Association de mémoire interactive",
"game_memory_desc": "Associez les termes cibles avec leurs traductions et visuels correspondants pour renforcer la rétention sémantique.",
"game_monster_title": "Association conceptuelle (Monstre des mots)",
"game_monster_desc": "Sélectionnez et présentez la carte de traduction correspondant précisément au concept ciblé.",
"game_quiz_title": "Évaluation acoustique et visuelle",
"game_quiz_desc": "Écoutez la prononciation ou examinez l'indice visuel, puis identifiez le terme correspondant correct.",
"game_scramble_title": "Reconstruction orthographique",
"game_scramble_desc": "Réarrangez les lettres pour épeler correctement la traduction du mot cible.",
"game_linker_title": "Cartographie de correspondance visuelle",
"game_linker_desc": "Faites correspondre les cartes illustrées de gauche avec les mots d'entraînement à droite.",
"game_monster_feed_me": "FOURNIR LA CARTE POUR :",
"game_monster_correct": "Traduction correcte identifiée ! 🎉",
"game_monster_incorrect": "Carte incorrecte sélectionnée. 😢",
"game_monster_no_words": "La liste de vocabulaire est vide !",
"game_monster_no_words_desc": "Veuillez d'abord configurer vos préférences et générer des mots dans l'onglet 'Deck de vocabulaire'.",
"game_quiz_hint_btn": "Indice 💡",
"game_quiz_replay_audio": "Jouer l'audio 🔊",
"game_quiz_correct": "Correct ! 🎉",
"game_quiz_incorrect": "Incorrect ! Réessayez. 😢",
"game_quiz_question": "Identifiez ce terme :",
"game_quiz_need_four": "Veuillez générer au moins 4 mots pour initialiser l'Évaluation acoustique et visuelle.",
"game_scramble_clue_label": "Traduisez ce terme :",
"game_scramble_explanation_label": "Indice de définition :",
"game_scramble_reset_btn": "Réinitialiser 🔄",
"game_scramble_play_audio": "Prononcer 🔊",
"game_scramble_correct": "Orthographe parfaite ! 🎉",
"game_scramble_incorrect": "Incorrect. Réessayez.",
"game_memory_moves": "Mouvements :",
"game_memory_congrats": "Succès ! Toutes les associations ont été trouvées. 🎉",
"game_memory_need_words": "Générez au moins 4 mots pour démarrer l'Association de mémoire interactive.",
"game_linker_instruction": "Sélectionnez une carte visuelle à gauche, puis associez-la au mot correspondant à droite.",
"game_linker_hint_btn": "Indice 💡",
"game_linker_correct": "Association parfaite ! 🎉",
"game_linker_incorrect": "Incompatibilité ! Réessayez. 😢",
"game_linker_select_clue": "Sélectionnez d'abord une carte à gauche pour obtenir un indice.",
"game_linker_need_words": "Générez au moins 4 mots pour jouer à la Cartographie de correspondance visuelle."
},
"German": {
"title": "📘 WordConjure: Multimodales Vokabeltraining",
"subtitle": "Eine Plattform zur Vokabelerweiterung mit kontextbezogenen Erklärungen, visuellen Karten und klaren Aussprachebeispielen für ein strukturiertes Lernen.",
"tutorial_text": "Zuerst: Wählen Sie unten Ihre Einstellungen und klicken Sie auf \"Vokabeln generieren\", um Ihren Lernstapel zu laden. Danach: Wechseln Sie oben auf den Reiter \"Übungsbereich\", um Ihr Gedächtnis mit interaktiven Spielen zu testen.",
"settings": "⚙️ Sitzungskonfiguration",
"word_count_label": "🔢 Anzahl der zu generierenden Wörter:",
"expl_lang_label": "🗣️ Erklärungssprache",
"app_lang_label": "📱 App-Sprache",
"source_lang": "🌍 Ausgangssprache (Muttersprache)",
"target_lang": "🎯 Zielsprache zum Üben",
"btn_get_words": "⚡ Vokabeln generieren",
"tab_vocab": "📖 Vokabel-Stapel",
"tab_games": "🎮 Übungsbereich",
"original_header": "Zielwort",
"translation_header": "Übersetzung",
"explanation_header": "Kontextbezogene Definition",
"visual_header": "Bildkarte",
"audio_header": "Aussprache",
"game_selection_title": "Wählen Sie eine Übungseinheit",
"game_memory_title": "Interaktive Gedächtnisassoziation",
"game_memory_desc": "Verbinden Sie Zielbegriffe mit ihren Übersetzungen und visuellen Karten, um die semantische Merkfähigkeit zu stärken.",
"game_monster_title": "Begriffszuordnung (Wortmonster)",
"game_monster_desc": "Wählen Sie die Übersetzungskarte aus, die genau zum gesuchten Begriff passt.",
"game_quiz_title": "Akustische & Visuelle Bewertung",
"game_quiz_desc": "Hören Sie sich die Aussprache an oder prüfen Sie die Bildkarte, um den passenden Begriff auszuwählen.",
"game_scramble_title": "Orthographische Rekonstruktion",
"game_scramble_desc": "Bringen Sie die durcheinandergewürfelten Buchstaben in die richtige Reihenfolge, um den Begriff korrekt zu schreiben.",
"game_linker_title": "Visuelle Begriffsverknüpfung",
"game_linker_desc": "Verbinden Sie die Bildkarten auf der linken Seite mit den Übungswörtern auf der rechten Seite.",
"game_monster_feed_me": "KARTE PRÄSENTIEREN FÜR:",
"game_monster_correct": "Richtige Übersetzung zugeordnet! 🎉",
"game_monster_incorrect": "Falsche Karte ausgewählt. 😢",
"game_monster_no_words": "Vokabelliste ist leer!",
"game_monster_no_words_desc": "Bitte kehren Sie zum Reiter 'Vokabel-Stapel' zurück und wählen Sie 'Vokabeln generieren'.",
"game_quiz_hint_btn": "Hinweis 💡",
"game_quiz_replay_audio": "Audio abspielen 🔊",
"game_quiz_correct": "Richtig! 🎉",
"game_quiz_incorrect": "Falsch! Versuchen Sie es noch einmal. 😢",
"game_quiz_question": "Identifizieren Sie diesen Begriff:",
"game_quiz_need_four": "Bitte generieren Sie mindestens 4 Wörter für die akustische und visuelle Bewertung.",
"game_scramble_clue_label": "Übersetzen Sie diesen Begriff:",
"game_scramble_explanation_label": "Definitionshinweis:",
"game_scramble_reset_btn": "Zurücksetzen 🔄",
"game_scramble_play_audio": "Anhören 🔊",
"game_scramble_correct": "Perfekte Rechtschreibung! 🎉",
"game_scramble_incorrect": "Fehlerhaft. Versuchen Sie es noch einmal.",
"game_memory_moves": "Züge:",
"game_memory_congrats": "Erfolgreich gelöst! Alle Zuordnungen stimmen. 🎉",
"game_memory_need_words": "Bitte generieren Sie mindestens 4 Wörter für die interaktive Gedächtnisassoziation.",
"game_linker_instruction": "Wählen Sie links eine Bildkarte aus und ordnen Sie sie dem passenden Übungswort rechts zu.",
"game_linker_hint_btn": "Hinweis 💡",
"game_linker_correct": "Perfekte Zuordnung! 🎉",
"game_linker_incorrect": "Keine Übereinstimmung. Versuchen Sie es noch einmal. 😢",
"game_linker_select_clue": "Wählen Sie zuerst links eine Karte aus, um einen Hinweis zu erhalten.",
"game_linker_need_words": "Bitte generieren Sie mindestens 4 Wörter für die visuelle Begriffsverknüpfung."
},
"Chinese": {
"title": "📘 WordConjure: 多模态词汇训练系统",
"subtitle": "一个针对多语种学习的词汇训练系统,通过自动生成上下文释义、视觉配图卡片与纯正发音,帮助学习者巩固语言记忆。",
"tutorial_text": "首先:在下方选择您的设置并点击“生成训练词汇”以加载您的多模态词汇卡组。然后:切换到上方的“强化练习”标签页,通过互动游戏测试您的记忆效果。",
"settings": "⚙️ 系统配置面板",
"word_count_label": "🔢 词汇生成数量:",
"expl_lang_label": "🗣️ 释义语言选项",
"app_lang_label": "📱 应用显示语言",
"source_lang": "🌍 母语 (源语言)",
"target_lang": "🎯 练习目标语言",
"btn_get_words": "⚡ 生成训练词汇",
"tab_vocab": "📖 词汇卡组",
"tab_games": "🎮 强化练习",
"original_header": "目标词汇",
"translation_header": "词汇翻译",
"explanation_header": "上下文释义",
"visual_header": "视觉配图",
"audio_header": "语音发音",
"game_selection_title": "选择强化训练模式",
"game_memory_title": "双向记忆关联",
"game_memory_desc": "翻转卡片进行目标词汇、翻译词汇和视觉插图的多维度记忆匹配。",
"game_monster_title": "概念具象识别 (单词怪兽)",
"game_monster_desc": "根据指示的概念要求,准确提交匹配的翻译词汇卡片。",
"game_quiz_title": "视听综合测验",
"game_quiz_desc": "通过听辨语音发音或观察视觉卡片,从多个备选项中选出正确目标词汇。",
"game_scramble_title": "词形拼写重建",
"game_scramble_desc": "将打乱的字母重新排列,拼写出目标翻译词汇的正确拼写形式。",
"game_linker_title": "双侧视觉连线",
"game_linker_desc": "将左侧生成的视觉卡片与右侧相应的目标词汇建立一对一关联。",
"game_monster_feed_me": "请提交对应的卡片:",
"game_monster_correct": "匹配正确!🎉",
"game_monster_incorrect": "匹配错误,请重试。😢",
"game_monster_no_words": "训练词汇卡组为空!",
"game_monster_no_words_desc": "请先返回“词汇卡组”标签页,选择目标语言并点击“生成训练词汇”。",
"game_quiz_hint_btn": "提示 💡",
"game_quiz_replay_audio": "重播音频 🔊",
"game_quiz_correct": "回答正确!🎉",
"game_quiz_incorrect": "回答错误,请重试!😢",
"game_quiz_question": "请识别此词汇:",
"game_quiz_need_four": "请至少生成 4 个词汇以开启视听综合测验。",
"game_scramble_clue_label": "翻译该词汇:",
"game_scramble_explanation_label": "释义线索:",
"game_scramble_reset_btn": "重置 🔄",
"game_scramble_play_audio": "发音 🔊",
"game_scramble_correct": "拼写完全正确!🎉",
"game_scramble_incorrect": "拼写错误,请重试。",
"game_memory_moves": "操作步数:",
"game_memory_congrats": "恭喜!全部卡片匹配成功。🎉",
"game_memory_need_words": "请至少生成 4 个词汇以开启双向记忆关联模式。",
"game_linker_instruction": "先点击左侧的视觉卡片,然后对应右侧的目标词汇进行关联。",
"game_linker_hint_btn": "提示 💡",
"game_linker_correct": "关联正确!🎉",
"game_linker_incorrect": "不匹配,请重试。😢",
"game_linker_select_clue": "请先选择左侧的卡片以获取线索提示!",
"game_linker_need_words": "请至少生成 4 个词汇以开启双侧视觉连线模式。"
},
"Japanese": {
"title": "📘 WordConjure:多言語対応語彙トレーニング",
"subtitle": "コンテキスト解説、イラストカード、標準音声ガイダンスを自動生成し、体系的な学習体験を提供する言語トレーニングシステムです。",
"tutorial_text": "まず最初に:以下で設定を選択し、「単語リストを生成」をクリックして単語デッキを読み込みます。次に:上の**「実践トレーニング」**タブに切り替えて、インタラクティブなゲームで記憶力をテストします。",
"settings": "⚙️ セッション設定",
"word_count_label": "🔢 生成する単語数:",
"expl_lang_label": "🗣️ 解説言語の選択",
"app_lang_label": "📱 アプリ表示言語",
"source_lang": "🌍 母国語(ソース)",
"target_lang": "🎯 練習する対象言語",
"btn_get_words": "⚡ 単語リストを生成",
"tab_vocab": "📖 語彙カードデッキ",
"tab_games": "🎮 実践トレーニング",
"original_header": "対象単語",
"translation_header": "翻訳",
"explanation_header": "コンテキスト解説",
"visual_header": "イラストカード",
"audio_header": "音声発音",
"game_selection_title": "演習メニューの選択",
"game_memory_title": "インタラクティブメモリ連想",
"game_memory_desc": "対象の言葉と翻訳、対応するイラストカードを神経衰弱方式でマッチングさせ、意味論的な定着を促します。",
"game_monster_title": "ターゲット概念マッチング (単語モンスター)",
"game_monster_desc": "提示された指示概念に合う適切な翻訳カードを選択して提出します。",
"game_quiz_title": "視聴覚総合テスト",
"game_quiz_desc": "音声発音やイラストを確認し、複数の選択肢から正しい対象単語を識別します。",
"game_scramble_title": "スペル再構成演習",
"game_scramble_desc": "ランダムに並べ替えられたアルファベットを並べ替え、正しいスペルを完成させます。",
"game_linker_title": "バイラテラル・ビジュアルリンカー",
"game_linker_desc": "左側のイラストカードと右側の対応する練習用単語を正しく結びつけます。",
"game_monster_feed_me": "該当するカードを選択:",
"game_monster_correct": "正確な翻訳が識別されました!🎉",
"game_monster_incorrect": "正しくないカードが選択されました。😢",
"game_monster_no_words": "語彙カードデッキが空です!",
"game_monster_no_words_desc": "「語彙カードデッキ」タブに戻り、設定をしてから「単語リストを生成」を押してください。",
"game_quiz_hint_btn": "ヒント 💡",
"game_quiz_replay_audio": "音声を再再生 🔊",
"game_quiz_correct": "正解です!🎉",
"game_quiz_incorrect": "不正解です。もう一度お試しください。😢",
"game_quiz_question": "単語を特定してください:",
"game_quiz_need_four": "視聴覚テストを開始するには、少なくとも4つの単語を生成してください。",
"game_scramble_clue_label": "単語を翻訳してください:",
"game_scramble_explanation_label": "解説ヒント:",
"game_scramble_reset_btn": "リセット 🔄",
"game_scramble_play_audio": "発音する 🔊",
"game_scramble_correct": "完璧なスペルです!🎉",
"game_scramble_incorrect": "不正確です。もう一度お試しください。",
"game_memory_moves": "手数量:",
"game_memory_congrats": "お見事!すべてのカードが正しく一致しました。🎉",
"game_memory_need_words": "メモリ連想ゲームをプレイするには、少なくとも4つの単語を生成してください。",
"game_linker_instruction": "左側のカードを選択し、右側の対応する練習用の単語をペアにしてください。",
"game_linker_hint_btn": "ヒント 💡",
"game_linker_correct": "完璧なペアリングです!🎉",
"game_linker_incorrect": "不一致です。もう一度お試しください。😢",
"game_linker_select_clue": "ヒントを得るには、まず左側のカードを選択してください。",
"game_linker_need_words": "バイラテラルリンカーをプレイするには、少なくとも4つの単語を生成してください。"
},
"Korean": {
"title": "📘 WordConjure: 다중 감각 어휘 학습 시스템",
"subtitle": "어휘 습득을 극대화하기 위해 맞춤형 상황 맥락 정의, 시각적 카드, 원어민 발음 가이드를 자동 생성하는 다국어 연습 플랫폼입니다.",
"tutorial_text": "먼저: 아래에서 원하는 설정을 선택하고 \"어휘 생성하기\"를 클릭하여 맞춤형 어휘 덱을 불러오십시오. 그 다음: 상단의 \"연습 및 학습 모드\" 탭으로 이동하여 대화형 게임을 통해 암기 상태를 테스트해 보십시오.",
"settings": "⚙️ 세션 환경 설정",
"word_count_label": "🔢 생성할 단어 수:",
"expl_lang_label": "🗣️ 설명 표시 언어",
"app_lang_label": "📱 앱 표시 언어",
"source_lang": "🌍 모국어 (원래 언어)",
"target_lang": "🎯 학습 대상 언어",
"btn_get_words": "⚡ 어휘 생성하기",
"tab_vocab": "📖 학습 어휘 덱",
"tab_games": "🎮 연습 및 학습 모드",
"original_header": "학습 단어",
"translation_header": "번역",
"explanation_header": "맥락 설명",
"visual_header": "시각 카드",
"audio_header": "원어민 발음",
"game_selection_title": "연습 모드 선택",
"game_memory_title": "상호작용적 기억 연상",
"game_memory_desc": "단어와 번역, 이미지를 쌍으로 맞추어 인지적 어휘 유지력을 높입니다.",
"game_monster_title": "맥락 매칭 어휘 연결 (단어 몬스터)",
"game_monster_desc": "제시된 뜻에 정확하게 부합하는 번역 카드를 선택하여 제출하십시오.",
"game_quiz_title": "시각 및 청각 종합 평가",
"game_quiz_desc": "발음을 듣거나 시각 카드를 분석하여 객관식 보기 중 올바른 표제어를 찾으십시오.",
"game_scramble_title": "어휘 맞춤 스펠링 재구성",
"game_scramble_desc": "무작위로 뒤섞인 철자 배열을 가다듬어 정확한 번역 어휘를 완성하십시오.",
"game_linker_title": "시각 및 언어적 1:1 매핑",
"game_linker_desc": "좌측의 이미지 카드와 우측의 학습 단어를 선으로 연결하여 연상 작용을 견고히 합니다.",
"game_monster_feed_me": "다음 뜻에 해당되는 카드 선택:",
"game_monster_correct": "올바른 단어가 일치되었습니다! 🎉",
"game_monster_incorrect": "잘못된 카드를 선택했습니다. 😢",
"game_monster_no_words": "어휘 덱이 비어 있습니다!",
"game_monster_no_words_desc": "'학습 어휘 덱' 탭으로 돌아가 학습 단어를 먼저 생성해 주십시오.",
"game_quiz_hint_btn": "힌트 💡",
"game_quiz_replay_audio": "오디오 다시 듣기 🔊",
"game_quiz_correct": "정답입니다! 🎉",
"game_quiz_incorrect": "틀렸습니다. 다시 시도하십시오! 😢",
"game_quiz_question": "어휘를 인식하십시오:",
"game_quiz_need_four": "평가를 시작하려면 최소 4개 이상의 단어를 생성해 주십시오.",
"game_scramble_clue_label": "단어의 번역을 입력하십시오:",
"game_scramble_explanation_label": "정의 힌트:",
"game_scramble_reset_btn": "초기화 🔄",
"game_scramble_play_audio": "발음 듣기 🔊",
"game_scramble_correct": "스펠링이 일치합니다! 🎉",
"game_scramble_incorrect": "스펠링 오류입니다. 다시 시도해 주십시오.",
"game_memory_moves": "이동 횟수:",
"game_memory_congrats": "훌륭합니다! 모든 어휘 매칭이 완료되었습니다. 🎉",
"game_memory_need_words": "기억 연상 게임을 진행하려면 최소 4개 이상의 단어가 필요합니다.",
"game_linker_instruction": "왼쪽 카드를 선택하고 오른쪽의 어휘 중 올바른 단어를 매핑하십시오.",
"game_linker_hint_btn": "힌트 💡",
"game_linker_correct": "정확하게 매핑되었습니다! 🎉",
"game_linker_incorrect": "불일치합니다. 다시 연결하십시오. 😢",
"game_linker_select_clue": "힌트를 얻으려면 왼쪽 카드를 먼저 선택하십시오.",
"game_linker_need_words": "매핑 연습을 진행하려면 최소 4개 이상의 단어를 소환해야 합니다."
},
"Russian": {
"title": "📘 WordConjure: Мультимодальное изучение слов",
"subtitle": "Инструмент для эффективного освоения лексики, автоматически генерирующий контекстные определения, ассоциативные карточки и точные аудиопроизношения.",
"tutorial_text": "Сначала: выберите настройки ниже и нажмите «Сгенерировать слова», чтобы загрузить свой набор карточек. Затем: перейдите на вкладку «Практические упражнения» выше, чтобы проверить память в интерактивных играх.",
"settings": "⚙️ Конфигурация сессии",
"word_count_label": "🔢 Количество слов для генерации:",
"expl_lang_label": "🗣️ Язык определений",
"app_lang_label": "📱 Язык интерфейса",
"source_lang": "🌍 Родной язык (исходный)",
"target_lang": "🎯 Изучаемый язык (целевой)",
"btn_get_words": "⚡ Сгенерировать слова",
"tab_vocab": "📖 Набор карточек",
"tab_games": "🎮 Практические упражнения",
"original_header": "Целевое слово",
"translation_header": "Перевод",
"explanation_header": "Контекстное определение",
"visual_header": "Карточка",
"audio_header": "Произношение",
"game_selection_title": "Выберите практическое упражнение",
"game_memory_title": "Ассоциативное сопоставление",
"game_memory_desc": "Переворачивайте карточки, сопоставляя термины с их переводами и изображениями для глубокого закрепления.",
"game_monster_title": "Концептуальное сопоставление (Слово-монстр)",
"game_monster_desc": "Выберите карточку с правильным переводом, точно соответствующую запрашиваемому значению.",
"game_quiz_title": "Аудиовизуальная оценка",
"game_quiz_desc": "Определите верное слово на основе произношения или предложенной визуальной иллюстрации.",
"game_scramble_title": "Орфографическая реконструкция",
"game_scramble_desc": "Расположите перемешанные буквы в правильном порядке, чтобы верно записать перевод.",
"game_linker_title": "Визуальное сопоставление",
"game_linker_desc": "Установите точные соответствия между визуальными карточками слева и терминами справа.",
"game_monster_feed_me": "ПРЕДОСТАВЬТЕ КАРТОЧКУ ДЛЯ:",
"game_monster_correct": "Правильный перевод найден! 🎉",
"game_monster_incorrect": "Выбрана неверная карточка. 😢",
"game_monster_no_words": "Список слов пуст!",
"game_monster_no_words_desc": "Пожалуйста, вернитесь во вкладку 'Набор карточек', задайте настройки и нажмите 'Сгенерировать слова'.",
"game_quiz_hint_btn": "Подсказка 💡",
"game_quiz_replay_audio": "Повторить аудио 🔊",
"game_quiz_correct": "Верно! 🎉",
"game_quiz_incorrect": "Неверно! Попробуйте еще раз. 😢",
"game_quiz_question": "Определите этот термин:",
"game_quiz_need_four": "Пожалуйста, создайте не менее 4 слов для инициализации аудиовизуальной оценки.",
"game_scramble_clue_label": "Переведите этот термин:",
"game_scramble_explanation_label": "Определение для подсказки:",
"game_scramble_reset_btn": "Сбросить 🔄",
"game_scramble_play_audio": "Произнести 🔊",
"game_scramble_correct": "Отличное правописание! 🎉",
"game_scramble_incorrect": "Неверно. Попробуйте еще раз.",
"game_memory_moves": "Ходы:",
"game_memory_congrats": "Успех! Все карточки сопоставлены верно. 🎉",
"game_memory_need_words": "Необходимо сгенерировать не менее 4 слов, чтобы начать игру.",
"game_linker_instruction": "Выберите карточку слева, затем сопоставьте ее с нужным термином справа.",
"game_linker_hint_btn": "Подсказка 💡",
"game_linker_correct": "Отличное сопоставление! 🎉",
"game_linker_incorrect": "Не совпадает! Попробуйте еще раз. 😢",
"game_linker_select_clue": "Сначала выберите карточку слева, чтобы получить текстовую подсказку.",
"game_linker_need_words": "Пожалуйста, сгенерируйте минимум 4 слова для практического сопоставления."
},
"Portuguese": {
"title": "📘 WordConjure: Prática Multimodal de Vocabulário",
"subtitle": "Uma plataforma de treino de vocabulário que gera definições de contexto, cartões visuais e pronúncias de áudio claras para apoiar a aquisição de qualquer idioma.",
"tutorial_text": "Primeiro: selecione suas preferências abaixo e clique em \"Gerar Vocabulário\" para carregar seu deck de estudo. Depois: acesse a aba \"Exercícios Práticos\" acima para testar sua memória com jogos interativos.",
"settings": "⚙️ Configurações da Sessão",
"word_count_label": "🔢 Quantidade de palavras a gerar:",
"expl_lang_label": "🗣️ Idioma das Explicações",
"app_lang_label": "📱 Idioma do Aplicativo",
"source_lang": "🌍 Idioma Nativo (origem)",
"target_lang": "🎯 Idioma para Praticar (destino)",
"btn_get_words": "⚡ Gerar Vocabulário",
"tab_vocab": "📖 Deck de Vocabulário",
"tab_games": "🎮 Exercícios Práticos",
"original_header": "Palavra Alvo",
"translation_header": "Tradução",
"explanation_header": "Definição de Contexto",
"visual_header": "Cartão Visual",
"audio_header": "Pronúncia",
"game_selection_title": "Selecione o seu Exercício de Treino",
"game_memory_title": "Associação de Memória Interativa",
"game_memory_desc": "Combine os termos originais com as suas traduções e imagens para consolidar a fixação mental.",
"game_monster_title": "Associação Conceitual de Palavras (Monstro)",
"game_monster_desc": "Identifique e selecione o cartão de tradução que se adapta com precisão à definição solicitada.",
"game_quiz_title": "Avaliação Acústica e Visual",
"game_quiz_desc": "Analise a pronúncia ou a imagem e escolha o termo original correspondente a partir das escolhas fornecidas.",
"game_scramble_title": "Reconstrução Ortográfica",
"game_scramble_desc": "Reorganize a sequência de letras para soletrar de forma correta a tradução do termo.",
"game_linker_title": "Mapeamento Visual de Correspondência",
"game_linker_desc": "Associe diretamente cada cartão ilustrado na esquerda com a palavra de treino correspondente na direita.",
"game_monster_feed_me": "FORNEÇA A CARTA PARA:",
"game_monster_correct": "Tradução correta identificada! 🎉",
"game_monster_incorrect": "Cartão incorreto selecionado. 😢",
"game_monster_no_words": "O seu deck de vocabulário está vazio!",
"game_monster_no_words_desc": "Por favor, configure as preferências no 'Deck de Vocabulário' e selecione 'Gerar Vocabulário' primeiro.",
"game_quiz_hint_btn": "Dica 💡",
"game_quiz_replay_audio": "Tocar Áudio 🔊",
"game_quiz_correct": "Correto! 🎉",
"game_quiz_incorrect": "Incorreto! Tente de novo. 😢",
"game_quiz_question": "Identifique este termo:",
"game_quiz_need_four": "Invoque ou gere ao menos 4 palavras para iniciar a Avaliação Acústica e Visual.",
"game_scramble_clue_label": "Traduza este termo:",
"game_scramble_explanation_label": "Dica de definição:",
"game_scramble_reset_btn": "Redefinir 🔄",
"game_scramble_play_audio": "Pronunciar 🔊",
"game_scramble_correct": "Ortografia Perfeita! 🎉",
"game_scramble_incorrect": "Incorreto. Tente novamente.",
"game_memory_moves": "Jogadas:",
"game_memory_congrats": "Sucesso! Todas as combinações foram concluídas perfeitamente. 🎉",
"game_memory_need_words": "Crie ao menos 4 palavras no vocabulário para jogar a Associação de Memória.",
"game_linker_instruction": "Selecione o cartão visual na esquerda, depois associe-o com a palavra equivalente na direita.",
"game_linker_hint_btn": "Dica 💡",
"game_linker_correct": "Associação Perfeita! 🎉",
"game_linker_incorrect": "Incompatível! Tente de novo. 😢",
"game_linker_select_clue": "Selecione primeiro um cartão na esquerda para obter uma dica de contexto.",
"game_linker_need_words": "Gere ao menos 4 palavras para praticar o Mapeamento de Correspondência."
},
"Italian": {
"title": "📘 WordConjure: Pratica Multimodale del Vocabolario",
"subtitle": "Una piattaforma avanzata per lo studio dei vocaboli che genera definizioni contestuali, carte visive e guide di pronuncia audio per facilitare l'apprendimento delle lingue.",
"tutorial_text": "Prima: seleziona le tue preferenze qui sotto e clicca su \"Genera Vocabolario\" per caricare il tuo mazzo di studio. Poi: vai alla scheda \"Esercizi di Pratica\" in alto per testare la tua memoria con i giochi interattivi.",
"settings": "⚙️ Configurazione Sessione",
"word_count_label": "🔢 Numero di parole da generare:",
"expl_lang_label": "🗣️ Lingua delle Spiegazioni",
"app_lang_label": "📱 Lingua dell'Applicazione",
"source_lang": "🌍 Lingua Madre (origine)",
"target_lang": "🎯 Lingua da Praticare (destinazione)",
"btn_get_words": "⚡ Genera Vocabolario",
"tab_vocab": "📖 Mazzo di Vocaboli",
"tab_games": "🎮 Esercizi di Pratica",
"original_header": "Parola Obiettivo",
"translation_header": "Traduzione",
"explanation_header": "Definizione Contestuale",
"visual_header": "Carta Visiva",
"audio_header": "Pronuncia",
"game_selection_title": "Scegli il tuo Esercizio di Studio",
"game_memory_title": "Associazione di Memoria Interattiva",
"game_memory_desc": "Abbina i termini target con le corrispondenti traduzioni e carte visive per massimizzare la memorizzazione.",
"game_monster_title": "Associazione Concettuale (Mostro dei Vocaboli)",
"game_monster_desc": "Seleziona e presenta la carta di traduzione esatta corrispondente al concetto indicato.",
"game_quiz_title": "Valutazione Acustica e Visiva",
"game_quiz_desc": "Analizza il file audio o l'immagine e identifica il termine corretto tra le risposte multiple.",
"game_scramble_title": "Ricostruzione Ortografica",
"game_scramble_desc": "Ordina i caratteri disordinati per comporre l'esatta traduzione della parola obiettivo.",
"game_linker_title": "Mappe di Corrispondenza Visiva",
"game_linker_desc": "Fai corrispondere bilateralmente le carte e i vocaboli sul lato destro.",
"game_monster_feed_me": "FORNISCI LA CARTA PER:",
"game_monster_correct": "Traduzione corretta identificata! 🎉",
"game_monster_incorrect": "Carta errata selezionata. 😢",
"game_monster_no_words": "Il mazzo di vocaboli è vuoto!",
"game_monster_no_words_desc": "Ritorna alla scheda 'Mazzo di Vocaboli', definisci le opzioni e clicca su 'Genera Vocabolario' per iniziare.",
"game_quiz_hint_btn": "Suggerimento 💡",
"game_quiz_replay_audio": "Riproduci Audio 🔊",
"game_quiz_correct": "Corretto! 🎉",
"game_quiz_incorrect": "Incorretto! Riprova. 😢",
"game_quiz_question": "Identifica questo termine:",
"game_quiz_need_four": "Genera almeno 4 parole per avviare l'esercizio di Valutazione Acustica e Visiva.",
"game_scramble_clue_label": "Traduci questo termine:",
"game_scramble_explanation_label": "Suggerimento di definizione:",
"game_scramble_reset_btn": "Ripristina 🔄",
"game_scramble_play_audio": "Pronuncia 🔊",
"game_scramble_correct": "Ortografia Perfetta! 🎉",
"game_scramble_incorrect": "Incorretto. Riprova.",
"game_memory_moves": "Mosse:",
"game_memory_congrats": "Successo! Tutte le associazioni corrispondono perfettamente. 🎉",
"game_memory_need_words": "Genera almeno 4 parole per giocare con l'Associazione di Memoria.",
"game_linker_instruction": "Seleziona una carta visiva a sinistra, poi collegala alla parola di pratica corrispondente a destra.",
"game_linker_hint_btn": "Suggerimento 💡",
"game_linker_correct": "Associazione Perfetta! 🎉",
"game_linker_incorrect": "Incompatibile! Riprova. 😢",
"game_linker_select_clue": "Seleziona prima una carta a sinistra per ottenere una pista sul contesto.",
"game_linker_need_words": "Genera almeno 4 parole per giocare con le Mappe di Corrispondenza Visiva."
}
}
# Rest of app.py contents remain exactly unchanged to preserve exact execution paths
TTS_SPEAKER_MAPPING = {
"English": "Aiden",
"Spanish": "Ryan",
"French": "Serena",
"German": "Aiden",
"Chinese": "Serena",
"Japanese": "Ono_anna",
"Korean": "Sohee",
"Russian": "Aiden",
"Portuguese": "Ryan",
"Italian": "Ryan"
}
VOCAB_THEMES = [
"nature and environment", "travel and sightseeing", "cooking and ingredients",
"occupations and careers", "hobbies and creative pursuits", "emotions and personalities",
"household items and architecture", "animals and biology", "urban life and transportation",
"weather, seasons and environment", "shopping and daily routines", "sports, health and human body",
"science, space and technology", "art, music and performances", "academic studies and school items"
]
VOCAB_TYPES = [
"a mix of parts of speech", "action verbs", "descriptive adjectives", "useful nouns"
]
@app.api(name="get_localization")
def get_localization(user_native_lang: str) -> dict:
return LOCALIZATION_DATABASE.get(user_native_lang, LOCALIZATION_DATABASE["English"])
def query_llm(prompt: str, max_new_tokens: int = 512) -> str:
messages = [
{"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to("cuda:0")
generated_ids = llm_model.generate(
**model_inputs,
max_new_tokens=max_new_tokens,
temperature=0.8,
top_p=0.9
)
input_len = model_inputs.input_ids.shape[1]
response_tokens = generated_ids[0][input_len:]
return tokenizer.decode(response_tokens, skip_special_tokens=True).strip()
def extract_json_array(text: str) -> list:
cleaned = text.strip()
if cleaned.startswith("```json"):
cleaned = cleaned[7:]
if cleaned.endswith("```"):
cleaned = cleaned[:-3]
cleaned = cleaned.strip()
match = re.search(r'\[\s*\[.*\]\s*\]', cleaned, re.DOTALL)
if match:
try:
return json.loads(match.group(0))
except Exception:
pass
try:
return json.loads(cleaned)
except Exception as e:
print(f"Failed to parse JSON array: {e}")
return []
def generate_visual_base64(image_prompt: str) -> str:
prompt = f"A simple, clean, minimalist flat icon style illustration of {image_prompt}, high quality educational flashcard illustration, isolated on white background"
with torch.inference_mode():
image = sana_pipe(
prompt=prompt,
height=768,
width=768,
num_inference_steps=2,
guidance_scale=4.5
).images[0]
buffered = io.BytesIO()
image.save(buffered, format="PNG")
return base64.b64encode(buffered.getvalue()).decode("utf-8")
def generate_audio_base64(word: str, language: str) -> str:
speaker = TTS_SPEAKER_MAPPING.get(language, "Aiden")
with torch.inference_mode():
wavs, sr = tts_model.generate_custom_voice(
text=word,
language=language,
speaker=speaker,
instruct="A clear, natural, and direct voice with a calm and stable tone. Moderate speed, no emotion, and neutral inflection.",
non_streaming_mode=True,
max_new_tokens=50,
)
audio_data = wavs[0]
buffered = io.BytesIO()
sf.write(buffered, audio_data, sr, format="WAV")
return base64.b64encode(buffered.getvalue()).decode("utf-8")
@app.api(name="get_translations")
@spaces.GPU(duration=30)
def get_translations(source_lang: str, target_lang: str, word_count: int, explanation_lang: str) -> list[list[str]]:
explanation_lang_target = source_lang if explanation_lang == "source" else target_lang
selected_category = random.choice(VOCAB_THEMES)
selected_type = random.choice(VOCAB_TYPES)
random_seed = random.randint(100000, 999999)
prompt = f"""You are a professional multilingual translator.
Generate a vocabulary list of exactly {word_count} words or phrases for language learning.
Source Language: {source_lang}
Practice/Target Language: {target_lang}
To ensure high variety and prevent repeating standard words across sessions, apply the following randomized criteria to select your words:
- Focus Topic/Theme: {selected_category}
- Grammar/Category: {selected_type}
- Generation Session Key: {random_seed}
Ensure you select unique and engaging vocabulary. Avoid simple introductory words like "dog", "hello", "goodbye", or "cat" unless they directly fit the requested focus topic.
For each item, generate:
1. The source word or phrase.
2. The target translation.
3. A short, simple, clear, and friendly explanation (maximum 2 sentences) written in the {explanation_lang_target} language.
4. An explicit, highly-descriptive illustration prompt in English, designed specifically for a text-to-image generator.
You must return ONLY a raw JSON list of lists of strings, where each sublist contains exactly:
[source_word, target_translation, explanation, english_image_prompt]
Do not include any chat commentary, introduction, or explanations outside the JSON array."""
response = query_llm(prompt, 1024)
print(response)
raw_pairs = extract_json_array(response)
validated_pairs = []
for item in raw_pairs:
if isinstance(item, list) and len(item) >= 4:
validated_pairs.append([str(item[0]), str(item[1]), str(item[2]), str(item[3])])
elif isinstance(item, list) and len(item) == 3:
validated_pairs.append([str(item[0]), str(item[1]), str(item[2]), f"a minimalist illustration representing {item[1]}"])
elif isinstance(item, list) and len(item) == 2:
validated_pairs.append([str(item[0]), str(item[1]), "", f"a minimalist illustration representing {item[1]}"])
selected_words = validated_pairs[:word_count]
visuals = []
for item in selected_words:
image_prompt = item[3]
try:
visual_b64 = generate_visual_base64(image_prompt)
except Exception as e:
print(f"Error generating visual card with prompt '{image_prompt}': {e}")
visual_b64 = ""
visuals.append(visual_b64)
audios = []
for item in selected_words:
target_word = item[1]
try:
audio_b64 = generate_audio_base64(target_word, target_lang)
except Exception as e:
print(f"Error generating audio track for '{target_word}': {e}")
audio_b64 = ""
audios.append(audio_b64)
results = []
for idx, (original, translated, explanation, _) in enumerate(selected_words):
results.append([
original,
translated,
explanation,
visuals[idx],
audios[idx]
])
return results
@app.get("/", response_class=HTMLResponse)
def homepage():
html_path = "index.html"
with open(html_path, "r", encoding="utf-8") as f:
return f.read()
if __name__ == "__main__":
app.launch(debug=True, show_error=True)