@rookiestar/eng-lang-tutor 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/.claude/settings.local.json +22 -0
  2. package/.gitignore +32 -0
  3. package/CHANGELOG.md +37 -0
  4. package/CLAUDE.md +275 -0
  5. package/README.md +369 -0
  6. package/SKILL.md +613 -0
  7. package/bin/eng-lang-tutor.js +177 -0
  8. package/docs/OPENCLAW_DEPLOYMENT.md +241 -0
  9. package/examples/sample_keypoint_a1.json +112 -0
  10. package/examples/sample_keypoint_a2.json +124 -0
  11. package/examples/sample_keypoint_b1.json +135 -0
  12. package/examples/sample_keypoint_b2.json +137 -0
  13. package/examples/sample_keypoint_c1.json +134 -0
  14. package/examples/sample_keypoint_c2.json +141 -0
  15. package/examples/sample_quiz_a1.json +94 -0
  16. package/examples/sample_quiz_a2.json +94 -0
  17. package/examples/sample_quiz_b1.json +92 -0
  18. package/examples/sample_quiz_b2.json +94 -0
  19. package/examples/sample_quiz_c1.json +94 -0
  20. package/examples/sample_quiz_c2.json +104 -0
  21. package/package.json +41 -0
  22. package/references/resources.md +292 -0
  23. package/requirements.txt +16 -0
  24. package/scripts/__init__.py +28 -0
  25. package/scripts/audio/__init__.py +23 -0
  26. package/scripts/audio/composer.py +367 -0
  27. package/scripts/audio/converter.py +331 -0
  28. package/scripts/audio/feishu_voice.py +404 -0
  29. package/scripts/audio/tts/__init__.py +30 -0
  30. package/scripts/audio/tts/base.py +166 -0
  31. package/scripts/audio/tts/manager.py +306 -0
  32. package/scripts/audio/tts/providers/__init__.py +12 -0
  33. package/scripts/audio/tts/providers/edge.py +111 -0
  34. package/scripts/audio/tts/providers/xunfei.py +205 -0
  35. package/scripts/audio/utils.py +63 -0
  36. package/scripts/cli/__init__.py +7 -0
  37. package/scripts/cli/cli.py +229 -0
  38. package/scripts/cli/command_parser.py +336 -0
  39. package/scripts/core/__init__.py +30 -0
  40. package/scripts/core/constants.py +125 -0
  41. package/scripts/core/error_notebook.py +308 -0
  42. package/scripts/core/gamification.py +405 -0
  43. package/scripts/core/scorer.py +295 -0
  44. package/scripts/core/state_manager.py +814 -0
  45. package/scripts/eng-lang-tutor +16 -0
  46. package/scripts/scheduling/__init__.py +6 -0
  47. package/scripts/scheduling/cron_push.py +229 -0
  48. package/scripts/utils/__init__.py +12 -0
  49. package/scripts/utils/dedup.py +331 -0
  50. package/scripts/utils/helpers.py +82 -0
  51. package/templates/keypoint_schema.json +420 -0
  52. package/templates/prompt_templates.md +73 -0
  53. package/templates/prompts/display_guide.md +106 -0
  54. package/templates/prompts/initialization.md +350 -0
  55. package/templates/prompts/keypoint_generation.md +272 -0
  56. package/templates/prompts/output_rules.md +106 -0
  57. package/templates/prompts/quiz_generation.md +190 -0
  58. package/templates/prompts/responses.md +339 -0
  59. package/templates/prompts/shared_enums.md +252 -0
  60. package/templates/quiz_schema.json +214 -0
  61. package/templates/state_schema.json +277 -0
@@ -0,0 +1,350 @@
1
+ # Initialization Flow Templates
2
+
3
+ > Templates for the 7-step onboarding process when a new user starts.
4
+
5
+ **Related Files:**
6
+ - [shared_enums.md](shared_enums.md) - CEFR levels, topics, tutor styles
7
+
8
+ **IMPORTANT Display Rules:**
9
+ - Every step MUST display ALL options with numbers (1, 2, 3...)
10
+ - Every step MUST show the recommended/default option clearly
11
+ - Model MUST NOT skip any options or abbreviate the list
12
+ - User can reply with number or text (both should work)
13
+
14
+ ---
15
+
16
+ ## Step 0: Welcome Message
17
+
18
+ ```json
19
+ {
20
+ "type": "init_welcome",
21
+ "step": 0,
22
+ "display": {
23
+ "title": "👋 Welcome to American English Tutor!",
24
+ "message": "Hi! I'm your personal English tutor. I'll help you learn authentic American expressions that native speakers actually use.\n\nLet me ask you a few questions to personalize your learning experience.",
25
+ "prompt": "Ready to get started? Reply with **start** or **开始** to begin.",
26
+ "footer": "───────────────────\n🎯 This takes about 2 minutes"
27
+ }
28
+ }
29
+ ```
30
+
31
+ ---
32
+
33
+ ## Step 1: CEFR Level Selection
34
+
35
+ ```json
36
+ {
37
+ "type": "init_cefr",
38
+ "step": 1,
39
+ "display": {
40
+ "title": "📊 Step 1/7: Your English Level",
41
+ "message": "What's your current English level?",
42
+ "options": [
43
+ "**1.** A1-A2 - Beginner: Basic conversations, everyday words",
44
+ "**2.** B1-B2 - Intermediate: Work conversations, some idioms ⭐ Recommended",
45
+ "**3.** C1-C2 - Advanced: Complex topics, nuanced expressions"
46
+ ],
47
+ "default": "B1",
48
+ "prompt": "Reply with a number (1-3) or level (e.g., **2** or **B1**)",
49
+ "hint": "💡 Not sure? Most working professionals are B1-B2. You can change this later."
50
+ }
51
+ }
52
+ ```
53
+
54
+ **Input Mapping:**
55
+ | User Input | Value |
56
+ |------------|-------|
57
+ | 1, A1, A2, beginner | A2 |
58
+ | 2, B1, B2, intermediate | B1 |
59
+ | 3, C1, C2, advanced | C1 |
60
+
61
+ ---
62
+
63
+ ## Step 2: Topic Preferences
64
+
65
+ ```json
66
+ {
67
+ "type": "init_topics",
68
+ "step": 2,
69
+ "display": {
70
+ "title": "🎯 Step 2/7: Your Interests",
71
+ "message": "Which topics interest you most? (Select multiple)",
72
+ "options": [
73
+ "**1.** 🎬 movies - TV shows, films",
74
+ "**2.** 📰 news - Current events",
75
+ "**3.** 🎮 gaming - Video games",
76
+ "**4.** ⚽ sports - Sports & fitness",
77
+ "**5.** 🏢 workplace - Office & business ⭐ Popular",
78
+ "**6.** 💬 social - Friends & parties",
79
+ "**7.** 🏠 daily_life - Shopping, restaurants"
80
+ ],
81
+ "default": "workplace, social, daily_life",
82
+ "prompt": "Reply with numbers (e.g., **1 5 6** or **movies workplace social**)",
83
+ "hint": "💡 Select 2-4 topics. Popular combo: 5 6 7 (workplace + social + daily_life)"
84
+ }
85
+ }
86
+ ```
87
+
88
+ **Input Mapping:**
89
+ | User Input | Value |
90
+ |------------|-------|
91
+ | 1, movies | movies |
92
+ | 2, news | news |
93
+ | 3, gaming | gaming |
94
+ | 4, sports | sports |
95
+ | 5, workplace | workplace |
96
+ | 6, social | social |
97
+ | 7, daily, daily_life | daily_life |
98
+
99
+ ---
100
+
101
+ ## Step 3: Tutor Style
102
+
103
+ ```json
104
+ {
105
+ "type": "init_style",
106
+ "step": 3,
107
+ "display": {
108
+ "title": "🎭 Step 3/7: Tutor Style",
109
+ "message": "How should I teach you?",
110
+ "options": [
111
+ "**1.** 😄 humorous - Fun examples, jokes, pop culture ⭐ Recommended",
112
+ "**2.** 📚 rigorous - Detailed explanations, grammar focus",
113
+ "**3.** 😎 casual - Short & sweet, everyday language",
114
+ "**4.** 👔 professional - Business-focused, formal contexts"
115
+ ],
116
+ "default": "humorous",
117
+ "prompt": "Reply with a number (1-4) or style name (e.g., **1** or **humorous**)"
118
+ }
119
+ }
120
+ ```
121
+
122
+ **Input Mapping:**
123
+ | User Input | Value |
124
+ |------------|-------|
125
+ | 1, humorous, funny | humorous |
126
+ | 2, rigorous, serious | rigorous |
127
+ | 3, casual, relaxed | casual |
128
+ | 4, professional, formal | professional |
129
+
130
+ ---
131
+
132
+ ## Step 4: Oral/Written Ratio
133
+
134
+ ```json
135
+ {
136
+ "type": "init_ratio",
137
+ "step": 4,
138
+ "display": {
139
+ "title": "💬 Step 4/7: Speaking vs Writing",
140
+ "message": "What do you want to focus on?",
141
+ "options": [
142
+ "**1.** 🗣️ Mostly speaking (80%) - Daily conversations, casual chat",
143
+ "**2.** ⚖️ Balanced (50%) - Mix of speaking and writing",
144
+ "**3.** ✍️ Mostly writing (20%) - Emails, formal documents"
145
+ ],
146
+ "default": "70",
147
+ "prompt": "Reply with a number (1-3) or percentage 0-100 (e.g., **1** or **70**)",
148
+ "hint": "💡 Recommended: 70% speaking (most learners want to speak better)"
149
+ }
150
+ }
151
+ ```
152
+
153
+ **Input Mapping:**
154
+ | User Input | Value |
155
+ |------------|-------|
156
+ | 1, mostly speaking | 80 |
157
+ | 2, balanced | 50 |
158
+ | 3, mostly writing | 20 |
159
+ | 0-100 (number) | that number |
160
+
161
+ ---
162
+
163
+ ## Step 5: Schedule Configuration
164
+
165
+ ```json
166
+ {
167
+ "type": "init_schedule",
168
+ "step": 5,
169
+ "display": {
170
+ "title": "⏰ Step 5/7: Schedule Your Learning",
171
+ "message": "When should I send you daily content?",
172
+ "options": [
173
+ "**1.** Morning person: Keypoint 06:45, Quiz 22:45 ⭐ Recommended",
174
+ "**2.** Late riser: Keypoint 08:00, Quiz 23:00",
175
+ "**3.** Custom times (you specify)"
176
+ ],
177
+ "defaults": {
178
+ "keypoint": "06:45",
179
+ "quiz": "22:45"
180
+ },
181
+ "prompt": "Reply with a number (1-3) or custom times (e.g., **1** or **07:00 21:30**)",
182
+ "hint": "💡 Quiz time must be later than keypoint time. Press Enter for defaults."
183
+ }
184
+ }
185
+ ```
186
+
187
+ **Input Mapping:**
188
+ | User Input | Keypoint | Quiz |
189
+ |------------|----------|------|
190
+ | 1, default, enter | 06:45 | 22:45 |
191
+ | 2, late | 08:00 | 23:00 |
192
+ | 3, HH:MM HH:MM | first time | second time |
193
+
194
+ **Validation Rules:**
195
+ - Both times must be in HH:MM format (24-hour)
196
+ - Quiz time must be later than keypoint time
197
+ - If user only provides one time, ask for the second
198
+ - If invalid format, show error and re-prompt
199
+
200
+ ---
201
+
202
+ ## Step 6: Voice Teaching Configuration
203
+
204
+ ```json
205
+ {
206
+ "type": "init_voice",
207
+ "step": 6,
208
+ "display": {
209
+ "title": "🔊 Step 6/7: Voice Teaching",
210
+ "message": "Would you like audio versions of knowledge points for listening practice?",
211
+ "options": [
212
+ "**1.** 🔊 Yes - Enable voice teaching ⭐ Recommended",
213
+ "**2.** 🔇 No - Text only, no audio"
214
+ ],
215
+ "speed_options": {
216
+ "description": "If yes, choose your preferred speech speed:",
217
+ "options": [
218
+ "**1.** Very slow (0.5x) - Beginner shadowing",
219
+ "**2.** Slow (0.7x) - Learning pronunciation",
220
+ "**3.** Normal (0.9x) - Daily learning ⭐ Recommended",
221
+ "**4.** Fast (1.3x) - Listening challenge",
222
+ "**5.** Very fast (1.7x) - Advanced training"
223
+ ]
224
+ },
225
+ "default": "yes 3",
226
+ "prompt": "Reply with **1** or **2**. If yes, also pick speed (e.g., **1** or **1 3** or **yes 3**)",
227
+ "hint": "💡 Recommended: Yes with normal speed (option 3). Great for commute listening!"
228
+ }
229
+ }
230
+ ```
231
+
232
+ **Input Mapping:**
233
+ | User Input | Enabled | Speed |
234
+ |------------|---------|-------|
235
+ | 1, yes, y | true | 0.9 (default) |
236
+ | 2, no, n | false | - |
237
+ | 1 3, yes 3 | true | 0.9 |
238
+ | 1 1, yes 1 | true | 0.5 |
239
+ | 1 2, yes 2 | true | 0.7 |
240
+ | 1 4, yes 4 | true | 1.3 |
241
+ | 1 5, yes 5 | true | 1.7 |
242
+
243
+ **State Update:**
244
+ ```json
245
+ {
246
+ "tts_settings": {
247
+ "enabled": true,
248
+ "provider": "edge-tts",
249
+ "speed": 0.9,
250
+ "voices": {
251
+ "narrator": null,
252
+ "dialogue_a": null,
253
+ "dialogue_b": null
254
+ }
255
+ }
256
+ }
257
+ ```
258
+ - If `voices` values are null, use provider defaults
259
+
260
+ ---
261
+
262
+ ## Step 7: Confirmation
263
+
264
+ ```json
265
+ {
266
+ "type": "init_confirm",
267
+ "step": 7,
268
+ "display": {
269
+ "title": "✅ All Set! Here's Your Profile:",
270
+ "summary": {
271
+ "level": "📊 Level: {cefr_level}",
272
+ "topics": "🎯 Topics: {top_topics}",
273
+ "style": "🎭 Style: {tutor_style}",
274
+ "focus": "💬 Focus: {oral_ratio}% speaking",
275
+ "schedule": "⏰ Schedule: Keypoint at {keypoint_time}, Quiz at {quiz_time}",
276
+ "voice": "🔊 Voice: {voice_status}"
277
+ },
278
+ "options": [
279
+ "**1.** ✅ Yes, confirm and start learning",
280
+ "**2.** ✏️ Change something"
281
+ ],
282
+ "prompt": "Reply with **1** or **yes** to confirm, or **2** to adjust.",
283
+ "footer": "───────────────────\n🚀 Your first lesson starts tomorrow!"
284
+ }
285
+ }
286
+ ```
287
+
288
+ **Voice Status Display:**
289
+ - If enabled: "Enabled, {speed_desc} speed"
290
+ - If disabled: "Disabled (text only)"
291
+
292
+ ---
293
+
294
+ ## Completion
295
+
296
+ ```json
297
+ {
298
+ "type": "init_complete",
299
+ "display": {
300
+ "title": "🎉 Welcome Aboard!",
301
+ "message": "You're all set! Here's what happens next:\n\n"
302
+ "☀️ **{keypoint_time}** - Daily knowledge point\n"
303
+ "🌙 **{quiz_time}** - Daily quiz",
304
+ "cron_setup": "I'll create cron jobs for your schedule now. You can change this anytime with the **schedule** command.",
305
+ "first_lesson": "Want your first lesson now? Reply **keypoint** or **知识点**",
306
+ "footer": "───────────────────\n💡 Say **help** anytime to see all commands"
307
+ }
308
+ }
309
+ ```
310
+
311
+ ---
312
+
313
+ ## Cron Job Creation (after Step 7 confirmation)
314
+
315
+ After user confirms with "yes" or "1", MUST execute the following bash commands to create cron jobs:
316
+
317
+ ```bash
318
+ # Parse times from schedule
319
+ KEYPOINT_TIME="06:45" # Default, replace with user's keypoint_time
320
+ QUIZ_TIME="22:45" # Default, replace with user's quiz_time
321
+
322
+ # Extract hour and minute
323
+ KEYPOINT_HOUR=$(echo $KEYPOINT_TIME | cut -d: -f1)
324
+ KEYPOINT_MIN=$(echo $KEYPOINT_TIME | cut -d: -f2)
325
+ QUIZ_HOUR=$(echo $QUIZ_TIME | cut -d: -f1)
326
+ QUIZ_MIN=$(echo $QUIZ_TIME | cut -d: -f2)
327
+
328
+ # Create cron jobs using openclaw
329
+ # Keypoint job
330
+ ${KEYPOINT_MIN} ${KEYPOINT_HOUR} * * * openclaw system event --text "Use eng-lang-tutor skill. Push today's keypoint." --mode now
331
+
332
+ # Quiz job
333
+ ${QUIZ_MIN} ${QUIZ_HOUR} * * * openclaw system event --text "Use eng-lang-tutor skill. Push today's quiz invitation." --mode now
334
+ ```
335
+
336
+ **IMPORTANT:** The cron job creation requires:
337
+ 1. Parse user's `keypoint_time` and `quiz_time` from state.json schedule
338
+ 2. Execute the bash command to register each cron job
339
+ 3. Log the event using `state_manager.py append_event`
340
+
341
+ **State Update:**
342
+ ```json
343
+ {
344
+ "schedule": {
345
+ "keypoint_time": "06:45",
346
+ "quiz_time": "22:45",
347
+ "timezone": "Asia/Shanghai"
348
+ }
349
+ }
350
+ ```
@@ -0,0 +1,272 @@
1
+ # Knowledge Point Generation Template
2
+
3
+ > Main template for generating daily English learning content.
4
+
5
+ **Related Files:**
6
+ - [shared_enums.md](shared_enums.md) - Topics, CEFR levels, tutor styles, quiz types
7
+ - [output_rules.md](output_rules.md) - JSON output rules, markdown formatting
8
+
9
+ ---
10
+
11
+ ## 1. Generation Prompt
12
+
13
+ ```markdown
14
+ You are an authentic American English tutor. Generate a daily knowledge point.
15
+
16
+ ## USER CONTEXT
17
+ - CEFR Level: {cefr_level} (A1=Beginner to C2=Proficient)
18
+ - Topic Focus: {topic} (movies/news/gaming/sports/workplace/social/daily_life)
19
+ - Tutor Style: {tutor_style} (humorous/rigorous/casual/professional)
20
+ - Expression Type: {oral_written_ratio}% oral expressions, {written_ratio}% written
21
+
22
+ ## RESOURCE REFERENCES
23
+ {topic_resources}
24
+
25
+ ## STRICT RULES
26
+ > **See [output_rules.md](output_rules.md) for complete JSON/Markdown formatting rules.**
27
+
28
+ 1. Focus on "How Americans say it" - NOT Chinese translations
29
+ 2. Must include: scene context, alternatives, Chinglish trap + correction
30
+ 3. Use authentic expressions from the resource references above
31
+ 4. Include pronunciation tips for casual speech (gonna, gotta, wanna, etc.)
32
+ 5. AVOID these recent topics (14-day dedup): {excluded_topics}
33
+ 6. **Include reference links** - provide authoritative sources for verification
34
+ 7. **Include formatted display object** - MUST include `display` object with all formatted fields using `**text**` for bold
35
+ 8. **Never use strikethrough** - Use ❌ emoji for wrong answers instead of `~~text~~`
36
+ 9. **NEVER add [AUDIO:...] tags** - Audio is handled separately by the system
37
+ ```
38
+
39
+ ---
40
+
41
+ ## 2. Reference Sources
42
+
43
+ When generating knowledge points, include links to these authoritative sources:
44
+
45
+ | Type | Source | URL Pattern | Description |
46
+ |------|--------|-------------|-------------|
47
+ | **Dictionary** | Merriam-Webster | `https://www.merriam-webster.com/dictionary/{phrase}` | Most authoritative American English dictionary |
48
+ | **Usage** | YouGlish | `https://youglish.com/pronounce/{phrase}/english/us` | Real YouTube videos with the phrase |
49
+ | **Etymology** | Etymonline | `https://www.etymonline.com/word/{word}` | Word origin and history |
50
+ | **Frequency** | Google Ngram | `https://books.google.com/ngrams/graph?content={phrase}` | Usage frequency over time |
51
+
52
+ **URL Encoding:** Replace spaces with `%20` in URLs.
53
+
54
+ **Reference Requirements:**
55
+ - `dictionary` is REQUIRED - always include Merriam-Webster link
56
+ - `usage_context` is REQUIRED - YouGlish helps users hear real usage
57
+ - `etymology` is OPTIONAL - include for interesting origin stories
58
+ - `frequency` is OPTIONAL - include for frequency comparison
59
+
60
+ **Example:**
61
+ ```json
62
+ {
63
+ "references": {
64
+ "dictionary": {
65
+ "source": "merriam-webster",
66
+ "url": "https://www.merriam-webster.com/dictionary/touch%20base",
67
+ "note": "Official definition and usage examples"
68
+ },
69
+ "usage_context": {
70
+ "source": "youglish",
71
+ "url": "https://youglish.com/pronounce/touch%20base/english/us",
72
+ "note": "Hear it in 1000+ real YouTube videos"
73
+ }
74
+ }
75
+ }
76
+ ```
77
+
78
+ ---
79
+
80
+ ## 3. Content Guidelines
81
+
82
+ ### Scene
83
+ - Describe a realistic situation where this expression is used
84
+ - Include formality level (casual/neutral/formal)
85
+ - Make it relatable to the CEFR level
86
+
87
+ ### Expressions
88
+ - Primary expression + 1-2 alternatives
89
+ - Include pronunciation tips for natural speech
90
+ - Usage notes explaining when to use
91
+
92
+ ### Chinglish Trap
93
+ - Show what Chinese speakers TYPICALLY say (the wrong version)
94
+ - Provide the correct American expression
95
+ - Explain WHY the wrong version sounds unnatural
96
+
97
+ ### Examples
98
+ - Use dialogue format with 2-3 exchanges
99
+ - Make conversations feel natural and authentic
100
+ - Include context for each dialogue
101
+
102
+ ---
103
+
104
+ ## 4. Output Schema
105
+
106
+ ```json
107
+ {
108
+ "_meta": {
109
+ "prompt_version": "keypoint_gen_v2.1"
110
+ },
111
+ "date": "{today_date}",
112
+ "topic_fingerprint": "unique_lowercase_with_underscores",
113
+ "category": "oral|written",
114
+ "topic": "{topic}",
115
+ "scene": {
116
+ "context": "Brief description of the situation",
117
+ "formality": "casual|neutral|formal"
118
+ },
119
+ "expressions": [
120
+ {
121
+ "phrase": "The American expression",
122
+ "pronunciation_tip": "How to say it naturally",
123
+ "usage_note": "When and how to use this"
124
+ }
125
+ ],
126
+ "alternatives": [
127
+ "Another way to say it 1",
128
+ "Another way to say it 2"
129
+ ],
130
+ "chinglish_trap": {
131
+ "wrong": "What Chinese speakers typically say",
132
+ "correct": "The natural American way",
133
+ "explanation": "Why the wrong version sounds off"
134
+ },
135
+ "examples": [
136
+ {
137
+ "situation": "Context for example",
138
+ "dialogue": ["Speaker A: ...", "Speaker B: ..."]
139
+ }
140
+ ],
141
+ "extended_learning": {
142
+ "related_phrases": ["phrase1", "phrase2"],
143
+ "cultural_note": "Brief cultural context",
144
+ "common_mistakes": ["mistake1"]
145
+ },
146
+ "references": {
147
+ "dictionary": {
148
+ "source": "merriam-webster",
149
+ "url": "https://www.merriam-webster.com/dictionary/{phrase}",
150
+ "note": "Definition and usage examples"
151
+ },
152
+ "usage_context": {
153
+ "source": "youglish",
154
+ "url": "https://youglish.com/pronounce/{phrase}/english/us",
155
+ "note": "Hear it in real YouTube videos"
156
+ }
157
+ },
158
+ "display": {
159
+ "title": "🏢 今日知识点 | Today's Knowledge Point",
160
+ "topic_tag": "🏷️ 主题: **{topic_name}** | {topic_name_en}",
161
+ "formality_tag": "📊 正式度: **{formality}**",
162
+ "scene_intro": "🎬 场景 | Scene",
163
+ "scene_text": "{scene_context}",
164
+ "expressions_title": "💬 核心表达 | Key Expressions",
165
+ "expressions_formatted": [
166
+ {
167
+ "emoji": "✨",
168
+ "phrase": "**{phrase}**",
169
+ "phrase_plain": "{phrase}",
170
+ "pronunciation": "🔊 {pronunciation_tip}",
171
+ "usage": "💡 {usage_note}"
172
+ }
173
+ ],
174
+ "alternatives_title": "🔄 其他说法 | Alternatives",
175
+ "alternatives_formatted": "• **{alt_1}**\n• **{alt_2}**",
176
+ "chinglish_title": "⚠️ Chinglish 陷阱 | Chinglish Trap",
177
+ "chinglish_formatted": "❌ Wrong: \"{wrong}\"\n✅ Correct: **{correct}**\n\n📝 {explanation}",
178
+ "examples_title": "🗣️ 对话示例 | Example Dialogues",
179
+ "examples_formatted": [
180
+ {
181
+ "situation_emoji": "☕",
182
+ "situation": "{situation_name}",
183
+ "dialogue": "💬 A: {line_1}\n💬 B: {line_2}",
184
+ "key_phrase_highlight": "**{key_phrase}**"
185
+ }
186
+ ],
187
+ "extended_title": "📚 延伸学习 | Extended Learning",
188
+ "extended_formatted": "🔗 Related: **{related_1}** | **{related_2}**\n\n🌎 {cultural_note}",
189
+ "references_title": "📖 权威参考 | References",
190
+ "references_formatted": "📚 [Merriam-Webster]({dict_url}) - {dict_note}\n🎬 [YouGlish]({usage_url}) - {usage_note}",
191
+ "footer": "───────────────────\n📅 {date} | 📝 Take the quiz to earn XP!"
192
+ }
193
+ }
194
+ ```
195
+
196
+ ---
197
+
198
+ ## 5. Topic Resource Injection
199
+
200
+ When generating content, inject topic-specific resources:
201
+
202
+ ```python
203
+ TOPIC_RESOURCES = {
204
+ "movies": """
205
+ Reference expressions from TV shows:
206
+ - Friends: "How you doin'?", "Could I BE any more...?"
207
+ - The Office: "That's what she said", "Touch base"
208
+ - Gossip Girl: "No offense", "None taken", "Done and done"
209
+ Focus on: dialogue patterns, humor, sarcasm, casual speech
210
+ """,
211
+
212
+ "news": """
213
+ Reference vocabulary from:
214
+ - CNN 10: Current events, clear explanations
215
+ - VOA: Simplified news vocabulary
216
+ Focus on: formal register, topic-specific vocabulary, clear structure
217
+ """,
218
+
219
+ "gaming": """
220
+ Reference gaming terminology:
221
+ - Core: NPC, spawn, loot, grind, level up, buff, nerf
222
+ - Multiplayer: party, squad, GG, clutch, carry
223
+ - Slang in daily use: "That was clutch", "GG"
224
+ Focus on: casual speech, slang, gaming-specific vocabulary
225
+ """,
226
+
227
+ "sports": """
228
+ Reference sports vocabulary:
229
+ - Basketball: dunk, buzzer beater, pick and roll
230
+ - Sports idioms: "step up to the plate", "ballpark figure"
231
+ Focus on: energetic expressions, idioms used in business
232
+ """,
233
+
234
+ "workplace": """
235
+ Reference workplace expressions:
236
+ - Office idioms: touch base, circle back, bandwidth
237
+ - Meeting phrases: "Let's get the ball rolling", "wrap up"
238
+ - Email language: formal yet natural
239
+ Focus on: professional communication, formal/informal switching
240
+ """,
241
+
242
+ "social": """
243
+ Reference social expressions:
244
+ - Greetings: "What's up?", "How's it going?"
245
+ - Making plans: "Let's hang out", "grab coffee"
246
+ - Casual responses: "Not much, you?", "Can't complain"
247
+ Focus on: casual speech, fillers, natural conversation flow
248
+ """,
249
+
250
+ "daily_life": """
251
+ Reference daily life expressions:
252
+ - Shopping: "Just looking", "Can I get a discount?"
253
+ - Restaurant: "I'd like the...", "Check, please"
254
+ - Services: Asking for help, making requests
255
+ Focus on: practical communication, politeness strategies
256
+ """
257
+ }
258
+ ```
259
+
260
+ ---
261
+
262
+ ## 6. CEFR Level Guidelines
263
+
264
+ > See [shared_enums.md](shared_enums.md#cefr-levels-能力等级) for level definitions.
265
+
266
+ Adjust content complexity based on CEFR level.
267
+
268
+ ---
269
+
270
+ ## 7. Tutor Style Variations
271
+
272
+ > See [shared_enums.md](shared_enums.md#tutor-styles-导师风格) for style definitions.