Spaces:
Running
Running
File size: 7,165 Bytes
07bc9aa | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | """Tutor engine: builds system prompts with STRICT language isolation."""
from backend.language_config import LANGUAGES, LEVELS, CURRICULUM, get_vocabulary
from backend.teacher_profiles import TEACHERS
def build_system_prompt(target_lang, instruction_lang, level, topic_id, teacher_id):
"""Build the system prompt with strict language isolation rules."""
target = LANGUAGES.get(target_lang, {})
instruction = LANGUAGES.get(instruction_lang, {})
level_cfg = LEVELS.get(level, {})
teacher = TEACHERS.get(teacher_id, {})
target_name = target.get("name", target_lang)
instruction_name = instruction.get("name", instruction_lang)
target_script = target.get("script", "")
target_native = target.get("native_name", "")
topics = CURRICULUM.get(level, [])
topic_info = next((t for t in topics if t["id"] == topic_id), {})
topic_title = topic_info.get("title", topic_id)
vocab = get_vocabulary(target_lang, topic_id)
vocab_block = ""
if vocab:
vocab_lines = [f" - {v['word']} ({v['transliteration']}) = {v['meaning']}"
for v in vocab[:10]]
vocab_block = "Key vocabulary for this lesson:\n" + "\n".join(vocab_lines)
is_immersion = target_lang == instruction_lang
# --- STRICT LANGUAGE ISOLATION (MOST CRITICAL RULES) ---
if is_immersion:
lang_rules = f"""
=== ABSOLUTE LANGUAGE RULES (HIGHEST PRIORITY — NEVER VIOLATE) ===
You are in IMMERSION MODE. The student is learning {target_name} using {target_name} itself.
1. EVERY SINGLE WORD you write MUST be in {target_name} ({target_script} script).
2. DO NOT use ANY other language. Not a single word of English or any other language.
3. Explanations, grammar notes, encouragement — ALL in {target_name}.
4. If the student writes in another language, respond ONLY in {target_name} and gently guide them back.
=== END LANGUAGE RULES ===
"""
else:
lang_rules = f"""
=== ABSOLUTE LANGUAGE RULES (HIGHEST PRIORITY — NEVER VIOLATE) ===
The student is learning {target_name} and already knows {instruction_name}.
1. ALL your explanations, instructions, grammar notes, encouragement, and conversation MUST be in {instruction_name}.
2. Teach {target_name} words/phrases using {target_script} script.
3. NEVER use English unless the instruction language IS English.
4. NEVER use any language other than {target_name} (for teaching) and {instruction_name} (for explaining).
5. When presenting vocabulary, use this format:
[{target_name} word in {target_script}] ([transliteration]) — [{instruction_name} meaning]
6. Even small words like "means", "is called", "for example" MUST be in {instruction_name}.
7. If the student writes in {instruction_name}, respond in {instruction_name} while teaching {target_name} content.
8. If the student attempts {target_name}, praise them in {instruction_name} and provide corrections in {instruction_name}.
=== END LANGUAGE RULES ===
"""
# Teacher personality
teacher_traits = teacher.get("system_prompt_traits", "You are a helpful language teacher.")
greeting_style = teacher.get("greeting_style", "friendly")
# Honorifics
honorifics_note = ""
if target.get("has_honorifics"):
honorifics_note = f"\n{target_name} has formal/informal address. At {level} level, teach the polite/formal forms primarily."
prompt = f"""{lang_rules}
{teacher_traits}
You are teaching {target_name} ({target_native}) to a {level_cfg.get('name', level)} student.
Topic: {topic_title}
{honorifics_note}
Teaching guidelines for {level} level:
- Vocabulary limit: ~{level_cfg.get('vocab_limit', 500)} words
- Grammar: {level_cfg.get('grammar_complexity', 'simple')}
- Corrections: {level_cfg.get('correction_style', 'gentle')}
- Response length: {level_cfg.get('response_length', '3-6 sentences')}
{vocab_block}
Format rules:
- When introducing a new {target_name} word, always write it in {target_script} script first, then transliteration in parentheses.
- Use short, clear sentences.
- After teaching 2-3 new words, give a quick practice exercise.
- When sharing cultural context, wrap it in [CULTURAL NOTE: your note here] format.
- For mini-dialogues, use [DIALOGUE] and [/DIALOGUE] markers.
- For sentence builder exercises, use [SENTENCE_BUILDER: word1 | word2 | word3 | ...] format with the correct order.
Remember: The language rules above are ABSOLUTE. Never break them under any circumstances.
"""
return prompt.strip()
def build_greeting_prompt(target_lang, instruction_lang, level, topic_id, teacher_id):
"""Build the first greeting message prompt."""
target = LANGUAGES.get(target_lang, {})
instruction = LANGUAGES.get(instruction_lang, {})
teacher = TEACHERS.get(teacher_id, {})
target_name = target.get("name", target_lang)
instruction_name = instruction.get("name", instruction_lang)
greeting_style = teacher.get("greeting_style", "friendly")
topics = CURRICULUM.get(level, [])
topic_info = next((t for t in topics if t["id"] == topic_id), {})
topic_title = topic_info.get("title", topic_id)
is_immersion = target_lang == instruction_lang
if is_immersion:
return (
f"Greet the student in {target_name} only. Be {greeting_style}. "
f"Introduce yourself as {teacher.get('name', 'Teacher')} and say you'll be teaching "
f"'{topic_title}' today. Start with a warm greeting in {target_name} and "
f"introduce 1-2 basic words from the topic. Keep it short and encouraging. "
f"Remember: EVERYTHING must be in {target_name}."
)
else:
return (
f"Greet the student in {instruction_name}. Be {greeting_style}. "
f"Introduce yourself as {teacher.get('name', 'Teacher')} and say you'll be teaching "
f"{target_name} today, specifically '{topic_title}'. "
f"Say a common greeting in {target_name} with its {instruction_name} meaning. "
f"Keep it short and welcoming. Remember: explain everything in {instruction_name}, "
f"teach words in {target_name}."
)
def evaluate_pronunciation(user_text, expected_text):
"""Simple pronunciation scoring by comparing transcribed text to expected."""
if not user_text or not expected_text:
return {"score": 0, "feedback": "No text to compare"}
user_words = user_text.lower().strip().split()
expected_words = expected_text.lower().strip().split()
if not expected_words:
return {"score": 0, "feedback": "No expected text"}
matches = 0
for uw in user_words:
if uw in expected_words:
matches += 1
score = min(100, int((matches / len(expected_words)) * 100))
if score >= 90:
feedback = "Excellent pronunciation!"
elif score >= 70:
feedback = "Good attempt! A few sounds need practice."
elif score >= 50:
feedback = "Decent try! Keep practicing the tricky sounds."
else:
feedback = "Let's practice this phrase more. Listen carefully and try again."
return {"score": score, "feedback": feedback, "expected": expected_text, "heard": user_text}
|