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}