@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,420 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "keypoint_schema.json",
4
+ "title": "Knowledge Point",
5
+ "description": "Daily English learning knowledge point with emoji-enhanced display",
6
+ "type": "object",
7
+ "required": ["date", "topic_fingerprint", "category", "topic", "scene", "expressions", "alternatives", "chinglish_trap", "examples"],
8
+ "properties": {
9
+ "date": {
10
+ "type": "string",
11
+ "format": "date",
12
+ "description": "Date of this knowledge point (YYYY-MM-DD)"
13
+ },
14
+ "topic_fingerprint": {
15
+ "type": "string",
16
+ "pattern": "^[a-z0-9_]+$",
17
+ "description": "Unique identifier for deduplication (e.g., 'asking_favor_casual')"
18
+ },
19
+ "category": {
20
+ "type": "string",
21
+ "enum": ["oral", "written"],
22
+ "description": "Whether this is primarily spoken or written English"
23
+ },
24
+ "topic": {
25
+ "type": "string",
26
+ "enum": ["movies", "news", "gaming", "sports", "workplace", "social", "daily_life"],
27
+ "description": "The theme category for this knowledge point"
28
+ },
29
+ "scene": {
30
+ "type": "object",
31
+ "required": ["context", "formality"],
32
+ "properties": {
33
+ "context": {
34
+ "type": "string",
35
+ "description": "Brief description of the situation where this expression is used"
36
+ },
37
+ "formality": {
38
+ "type": "string",
39
+ "enum": ["casual", "neutral", "formal"],
40
+ "description": "Level of formality"
41
+ }
42
+ }
43
+ },
44
+ "expressions": {
45
+ "type": "array",
46
+ "minItems": 1,
47
+ "maxItems": 3,
48
+ "items": {
49
+ "type": "object",
50
+ "required": ["phrase", "usage_note"],
51
+ "properties": {
52
+ "phrase": {
53
+ "type": "string",
54
+ "description": "The American English expression"
55
+ },
56
+ "pronunciation_tip": {
57
+ "type": "string",
58
+ "description": "How to pronounce naturally (e.g., 'gonna' not 'going to')"
59
+ },
60
+ "usage_note": {
61
+ "type": "string",
62
+ "description": "When and how to use this expression"
63
+ }
64
+ }
65
+ }
66
+ },
67
+ "alternatives": {
68
+ "type": "array",
69
+ "minItems": 1,
70
+ "maxItems": 5,
71
+ "items": {
72
+ "type": "string"
73
+ },
74
+ "description": "Other ways to say the same thing"
75
+ },
76
+ "chinglish_trap": {
77
+ "type": "object",
78
+ "required": ["wrong", "correct", "explanation"],
79
+ "properties": {
80
+ "wrong": {
81
+ "type": "string",
82
+ "description": "What Chinese speakers typically say incorrectly"
83
+ },
84
+ "correct": {
85
+ "type": "string",
86
+ "description": "The natural American way to say it"
87
+ },
88
+ "explanation": {
89
+ "type": "string",
90
+ "description": "Why the wrong version sounds off or unnatural"
91
+ }
92
+ }
93
+ },
94
+ "examples": {
95
+ "type": "array",
96
+ "minItems": 1,
97
+ "maxItems": 3,
98
+ "items": {
99
+ "type": "object",
100
+ "required": ["situation", "dialogue"],
101
+ "properties": {
102
+ "situation": {
103
+ "type": "string",
104
+ "description": "Context for this example dialogue"
105
+ },
106
+ "dialogue": {
107
+ "type": "array",
108
+ "minItems": 2,
109
+ "items": {
110
+ "type": "string"
111
+ },
112
+ "description": "Example dialogue lines (e.g., ['A: Hey!', 'B: What\\'s up?'])"
113
+ }
114
+ }
115
+ }
116
+ },
117
+ "extended_learning": {
118
+ "type": "object",
119
+ "properties": {
120
+ "related_phrases": {
121
+ "type": "array",
122
+ "maxItems": 5,
123
+ "items": {
124
+ "type": "string"
125
+ },
126
+ "description": "Related expressions to explore"
127
+ },
128
+ "cultural_note": {
129
+ "type": "string",
130
+ "description": "Brief cultural context or usage tip"
131
+ },
132
+ "common_mistakes": {
133
+ "type": "array",
134
+ "maxItems": 3,
135
+ "items": {
136
+ "type": "string"
137
+ },
138
+ "description": "Common mistakes to avoid"
139
+ }
140
+ }
141
+ },
142
+ "references": {
143
+ "type": "object",
144
+ "description": "Authoritative reference links for verification and deep dive",
145
+ "properties": {
146
+ "dictionary": {
147
+ "type": "object",
148
+ "description": "Dictionary definition reference",
149
+ "properties": {
150
+ "source": {
151
+ "type": "string",
152
+ "enum": ["merriam-webster", "cambridge", "oxford", "dictionary.com"],
153
+ "description": "Dictionary source name"
154
+ },
155
+ "url": {
156
+ "type": "string",
157
+ "format": "uri",
158
+ "description": "Direct link to the definition"
159
+ },
160
+ "note": {
161
+ "type": "string",
162
+ "description": "Brief note about what you'll find (e.g., 'Definition and examples')"
163
+ }
164
+ },
165
+ "required": ["source", "url"]
166
+ },
167
+ "usage_context": {
168
+ "type": "object",
169
+ "description": "Real-world usage examples (video/context)",
170
+ "properties": {
171
+ "source": {
172
+ "type": "string",
173
+ "enum": ["youglish", "sentencestack", "tatoeba"],
174
+ "description": "Usage context source name"
175
+ },
176
+ "url": {
177
+ "type": "string",
178
+ "format": "uri",
179
+ "description": "Direct link to usage examples"
180
+ },
181
+ "note": {
182
+ "type": "string",
183
+ "description": "Brief note (e.g., 'Hear it in 500+ YouTube videos')"
184
+ }
185
+ },
186
+ "required": ["source", "url"]
187
+ },
188
+ "etymology": {
189
+ "type": "object",
190
+ "description": "Word origin and history (optional)",
191
+ "properties": {
192
+ "source": {
193
+ "type": "string",
194
+ "enum": ["etymonline", "wiktionary"],
195
+ "description": "Etymology source name"
196
+ },
197
+ "url": {
198
+ "type": "string",
199
+ "format": "uri",
200
+ "description": "Direct link to etymology"
201
+ },
202
+ "note": {
203
+ "type": "string",
204
+ "description": "Brief note about the origin"
205
+ }
206
+ }
207
+ },
208
+ "frequency": {
209
+ "type": "object",
210
+ "description": "Usage frequency data (optional)",
211
+ "properties": {
212
+ "source": {
213
+ "type": "string",
214
+ "enum": ["google-ngram", "corpus"],
215
+ "description": "Frequency data source"
216
+ },
217
+ "url": {
218
+ "type": "string",
219
+ "format": "uri",
220
+ "description": "Direct link to frequency chart"
221
+ },
222
+ "note": {
223
+ "type": "string",
224
+ "description": "Brief note (e.g., 'Usage trend since 1800')"
225
+ }
226
+ }
227
+ }
228
+ },
229
+ "required": ["dictionary", "usage_context"]
230
+ },
231
+ "display": {
232
+ "type": "object",
233
+ "description": "Emoji-enhanced display format for IM/chat interfaces",
234
+ "properties": {
235
+ "title": {
236
+ "type": "string",
237
+ "description": "Main title with emoji (e.g., '🏒 今ζ—₯ηŸ₯θ―†η‚Ή | Today\\'s Knowledge Point')"
238
+ },
239
+ "topic_tag": {
240
+ "type": "string",
241
+ "description": "Topic label with emoji (e.g., '🏷️ 主钘: 职场口语 | Workplace Oral')"
242
+ },
243
+ "formality_tag": {
244
+ "type": "string",
245
+ "description": "Formality level with emoji (e.g., 'πŸ“Š 正式度: δΈ­ζ€§ | Neutral')"
246
+ },
247
+ "scene_intro": {
248
+ "type": "string",
249
+ "description": "Scene section header with emoji"
250
+ },
251
+ "scene_text": {
252
+ "type": "string",
253
+ "description": "Brief scene description for quick reading"
254
+ },
255
+ "expressions_title": {
256
+ "type": "string",
257
+ "description": "Expressions section header with emoji"
258
+ },
259
+ "expressions_formatted": {
260
+ "type": "array",
261
+ "items": {
262
+ "type": "object",
263
+ "properties": {
264
+ "emoji": {
265
+ "type": "string",
266
+ "description": "Expression emoji (e.g., '✨')"
267
+ },
268
+ "phrase": {
269
+ "type": "string",
270
+ "description": "The phrase with bold formatting (e.g., '**Let\\'s touch base**')"
271
+ },
272
+ "phrase_plain": {
273
+ "type": "string",
274
+ "description": "The phrase without formatting (e.g., 'Let\\'s touch base')"
275
+ },
276
+ "pronunciation": {
277
+ "type": "string",
278
+ "description": "Pronunciation tip with emoji (e.g., 'πŸ”Š Sounds like...')"
279
+ },
280
+ "usage": {
281
+ "type": "string",
282
+ "description": "Usage note with emoji (e.g., 'πŸ’‘ Brief, informal check-in')"
283
+ }
284
+ }
285
+ }
286
+ },
287
+ "alternatives_title": {
288
+ "type": "string",
289
+ "description": "Alternatives section header with emoji"
290
+ },
291
+ "alternatives_formatted": {
292
+ "type": "string",
293
+ "description": "Bullet list of alternatives with emoji"
294
+ },
295
+ "chinglish_title": {
296
+ "type": "string",
297
+ "description": "Chinglish trap section header with emoji"
298
+ },
299
+ "chinglish_formatted": {
300
+ "type": "string",
301
+ "description": "Wrong/Correct comparison with emoji (❌/βœ…)"
302
+ },
303
+ "examples_title": {
304
+ "type": "string",
305
+ "description": "Examples section header with emoji"
306
+ },
307
+ "examples_formatted": {
308
+ "type": "array",
309
+ "items": {
310
+ "type": "object",
311
+ "properties": {
312
+ "situation_emoji": {
313
+ "type": "string",
314
+ "description": "Situation emoji (e.g., 'β˜•', 'πŸ“§')"
315
+ },
316
+ "situation": {
317
+ "type": "string",
318
+ "description": "Brief situation name"
319
+ },
320
+ "dialogue": {
321
+ "type": "string",
322
+ "description": "Formatted dialogue with speaker emoji and bold key phrases"
323
+ },
324
+ "key_phrase_highlight": {
325
+ "type": "string",
326
+ "description": "The highlighted key phrase with bold (e.g., '**touch base**')"
327
+ }
328
+ }
329
+ }
330
+ },
331
+ "extended_title": {
332
+ "type": "string",
333
+ "description": "Extended learning section header with emoji"
334
+ },
335
+ "extended_formatted": {
336
+ "type": "string",
337
+ "description": "Multi-line formatted extended learning content"
338
+ },
339
+ "references_title": {
340
+ "type": "string",
341
+ "description": "References section header with emoji (e.g., 'πŸ“– 权威参考 | References')"
342
+ },
343
+ "references_formatted": {
344
+ "type": "string",
345
+ "description": "Formatted reference links with markdown (e.g., 'πŸ“š [Merriam-Webster](url) - Description')"
346
+ },
347
+ "footer": {
348
+ "type": "string",
349
+ "description": "Footer with date info (no XP - keypoints are for learning only, XP comes from quizzes)"
350
+ }
351
+ }
352
+ },
353
+ "generated": {
354
+ "type": "boolean",
355
+ "default": false,
356
+ "description": "Whether LLM content has been fully generated. CRITICAL: Set to true after generation to prevent re-generation"
357
+ },
358
+ "audio": {
359
+ "type": "object",
360
+ "description": "Audio resources for this knowledge point (generated by TTS)",
361
+ "properties": {
362
+ "dialogue": {
363
+ "type": "array",
364
+ "description": "Dialogue audio files with speaker information",
365
+ "items": {
366
+ "type": "object",
367
+ "properties": {
368
+ "speaker": {
369
+ "type": "string",
370
+ "description": "Speaker identifier (A, B, etc.)"
371
+ },
372
+ "text": {
373
+ "type": "string",
374
+ "description": "The spoken text"
375
+ },
376
+ "audio_url": {
377
+ "type": "string",
378
+ "description": "Relative path to audio file (e.g., 'audio/2026-02-21/dialogue_0_0_A.mp3')"
379
+ },
380
+ "error": {
381
+ "type": "string",
382
+ "description": "Error message if audio generation failed"
383
+ }
384
+ }
385
+ }
386
+ },
387
+ "expressions": {
388
+ "type": "array",
389
+ "description": "Expression pronunciation audio files",
390
+ "items": {
391
+ "type": "object",
392
+ "properties": {
393
+ "text": {
394
+ "type": "string",
395
+ "description": "The expression phrase"
396
+ },
397
+ "audio_url": {
398
+ "type": "string",
399
+ "description": "Relative path to audio file (e.g., 'audio/2026-02-21/expression_1.mp3')"
400
+ },
401
+ "error": {
402
+ "type": "string",
403
+ "description": "Error message if audio generation failed"
404
+ }
405
+ }
406
+ }
407
+ },
408
+ "generated_at": {
409
+ "type": "string",
410
+ "format": "date-time",
411
+ "description": "When audio was generated (ISO 8601 format)"
412
+ },
413
+ "provider": {
414
+ "type": "string",
415
+ "description": "TTS provider used (e.g., 'xunfei', 'edge-tts')"
416
+ }
417
+ }
418
+ }
419
+ }
420
+ }
@@ -0,0 +1,73 @@
1
+ # LLM Prompt Templates Index
2
+
3
+ > Templates for generating English learning content.
4
+ > Use these templates with state.json data to generate personalized content.
5
+
6
+ ---
7
+
8
+ ## Template Files
9
+
10
+ This documentation has been split into focused modules for easier navigation:
11
+
12
+ ### Shared Files (Reference First)
13
+ | File | Purpose |
14
+ |------|---------|
15
+ | [prompts/shared_enums.md](prompts/shared_enums.md) | **Shared enums** - Topics, CEFR levels, tutor styles, quiz types, badges |
16
+ | [prompts/output_rules.md](prompts/output_rules.md) | **Output rules** - JSON format, markdown syntax, platform compatibility |
17
+
18
+ ### Generation Templates
19
+ | File | Purpose |
20
+ |------|---------|
21
+ | [prompts/keypoint_generation.md](prompts/keypoint_generation.md) | Knowledge point generation template, topic resources |
22
+ | [prompts/quiz_generation.md](prompts/quiz_generation.md) | Quiz generation template with question types |
23
+ | [prompts/initialization.md](prompts/initialization.md) | 7-step onboarding flow templates |
24
+
25
+ ### Display Templates
26
+ | File | Purpose |
27
+ |------|---------|
28
+ | [prompts/display_guide.md](prompts/display_guide.md) | Emoji usage and text formatting guidelines |
29
+ | [prompts/responses.md](prompts/responses.md) | Response templates for stats, config, errors, quiz results |
30
+
31
+ ---
32
+
33
+ ## Quick Reference
34
+
35
+ ### Generation Flow
36
+
37
+ 1. **Keypoint Generation** β†’ Use [keypoint_generation.md](prompts/keypoint_generation.md)
38
+ - Inject user context (CEFR, topic, style)
39
+ - Inject topic resources
40
+ - Apply dedup rules
41
+
42
+ 2. **Quiz Generation** β†’ Use [quiz_generation.md](prompts/quiz_generation.md)
43
+ - Based on today's keypoint
44
+ - 3 questions: multiple_choice + chinglish_fix + fill_blank/dialogue
45
+
46
+ 3. **Display Formatting** β†’ Use [display_guide.md](prompts/display_guide.md)
47
+ - Apply emojis consistently
48
+ - Bold key phrases
49
+ - Never use strikethrough
50
+
51
+ ### Key Rules
52
+
53
+ > See [prompts/output_rules.md](prompts/output_rules.md) for complete formatting rules.
54
+
55
+ 1. **Output ONLY valid JSON** - no markdown blocks, no extra text
56
+ 2. **Focus on "How Americans say it"** - NOT Chinese translations
57
+ 3. **Include display object** - formatted strings for IM display
58
+ 4. **Use `**text**` for bold** - never use `~~strikethrough~~`
59
+
60
+ ### Reference Sources
61
+
62
+ | Type | Source | URL Pattern |
63
+ |------|--------|-------------|
64
+ | Dictionary | Merriam-Webster | `https://www.merriam-webster.com/dictionary/{phrase}` |
65
+ | Usage | YouGlish | `https://youglish.com/pronounce/{phrase}/english/us` |
66
+
67
+ ---
68
+
69
+ ## Related Files
70
+
71
+ - [../references/resources.md](../references/resources.md) - Topic-specific learning resources
72
+ - [../examples/sample_keypoint.json](../examples/sample_keypoint.json) - Example keypoint output
73
+ - [../examples/sample_quiz.json](../examples/sample_quiz.json) - Example quiz output
@@ -0,0 +1,106 @@
1
+ # Emoji & Text Formatting Guide
2
+
3
+ > Guidelines for emoji decorations and markdown formatting in IM displays.
4
+ > Makes content more engaging, scannable, and visually consistent.
5
+
6
+ **Related Files:**
7
+ - [shared_enums.md](shared_enums.md) - Topic, category, formality, quiz type enums with emojis
8
+ - [output_rules.md](output_rules.md) - JSON output rules, markdown formatting, platform compatibility
9
+
10
+ ---
11
+
12
+ ## 1. Section Emojis
13
+
14
+ | Section | Emoji | Example |
15
+ |---------|-------|---------|
16
+ | Title | 🏒 | `🏒 今ζ—₯ηŸ₯θ―†η‚Ή \| Today's Knowledge Point` |
17
+ | Scene | 🎬 | `🎬 εœΊζ™― \| Scene` |
18
+ | Expressions | βœ¨πŸ’¬ | `✨ Let's touch base` |
19
+ | Pronunciation | πŸ”Š | `πŸ”Š Sounds like 'touch base'` |
20
+ | Usage | πŸ’‘ | `πŸ’‘ Brief, informal check-in` |
21
+ | Alternatives | πŸ”„ | `πŸ”„ 兢他说法 \| Alternatives` |
22
+ | Chinglish | βš οΈβŒβœ… | `❌ Wrong ... βœ… Correct` |
23
+ | Examples | πŸ—£οΈπŸ’­ | `πŸ—£οΈ 对话瀺例 \| Example Dialogues` |
24
+ | Extended | πŸ“š | `πŸ“š ε»ΆδΌΈε­¦δΉ  \| Extended Learning` |
25
+ | Cultural | 🌎 | `🌎 Cultural Note` |
26
+ | Mistakes | 🚫 | `🚫 Common Mistakes` |
27
+ | Related | πŸ”— | `πŸ”— Related phrases` |
28
+
29
+ ---
30
+
31
+ ## 2. Feedback Emojis
32
+
33
+ | Feedback | Emoji | Example |
34
+ |----------|-------|---------|
35
+ | Correct | βœ… | `βœ… Correct! 'Touch base' = quick check-in` |
36
+ | Wrong | ❌ | `❌ Not quite. Try again!` |
37
+ | XP | πŸ’Ž | `πŸ’Ž +10 XP` |
38
+ | Progress | ⬜⬜⬜⬜ | `⬜⬜⬜⬜ 0/4 questions` |
39
+ | Encourage | πŸ’ͺπŸš€ | `πŸ’ͺ Good luck! 加油! πŸš€` |
40
+
41
+ ---
42
+
43
+ ## 3. Situation Emojis for Examples
44
+
45
+ | Situation | Emoji |
46
+ |-----------|-------|
47
+ | Morning/coffee | β˜• |
48
+ | Email/message | πŸ“§ |
49
+ | Meeting | 🀝 |
50
+ | Phone call | πŸ“± |
51
+ | Office chat | πŸ’¬ |
52
+ | Lunch break | 🍱 |
53
+ | Slack/Teams | πŸ’¬ |
54
+
55
+ ---
56
+
57
+ ## 4. Display Object Structure
58
+
59
+ When generating content, include a `display` object with formatted strings:
60
+
61
+ ```json
62
+ {
63
+ "display": {
64
+ "title": "🏒 今ζ—₯ηŸ₯θ―†η‚Ή | Today's Knowledge Point",
65
+ "topic_tag": "🏷️ 主钘: 职场口语 | Workplace Oral",
66
+ "formality_tag": "πŸ“Š 正式度: δΈ­ζ€§ | Neutral",
67
+ "scene_intro": "🎬 εœΊζ™― | Scene",
68
+ "expressions_title": "πŸ’¬ 核心葨达 | Key Expressions",
69
+ "chinglish_title": "⚠️ Chinglish ι™·ι˜± | Chinglish Trap",
70
+ "examples_title": "πŸ—£οΈ 对话瀺例 | Example Dialogues",
71
+ "footer": "───────────────────\nπŸ“… 2026-02-20 | πŸ“ Take the quiz to earn XP!"
72
+ }
73
+ }
74
+ ```
75
+
76
+ ---
77
+
78
+ ## 5. Emoji Usage Rules
79
+
80
+ > See [output_rules.md](output_rules.md) for complete formatting rules.
81
+
82
+ 1. **Keep it readable**: Don't overuse emojis; 1-2 per line maximum
83
+ 2. **Be consistent**: Use the same emoji for the same concept
84
+ 3. **Bilingual labels**: Include both Chinese and English when appropriate
85
+ 4. **Visual hierarchy**: Use emojis to create visual sections
86
+ 5. **Positive tone**: Use encouraging emojis for feedback
87
+
88
+ ---
89
+
90
+ ## 6. Formatting Examples
91
+
92
+ > See [output_rules.md](output_rules.md) for complete formatting rules.
93
+
94
+ **Key phrase highlighting:**
95
+ ```json
96
+ {
97
+ "dialogue": "πŸ’¬ A: Hey, can we **touch base**?\nπŸ’¬ B: Sure!",
98
+ "key_phrase_highlight": "**touch base**"
99
+ }
100
+ ```
101
+
102
+ **Display object fields:**
103
+ | Field | Purpose | Example |
104
+ |-------|---------|---------|
105
+ | `phrase` | Bold key phrase | `**Let's touch base**` |
106
+ | `key_phrase_highlight` | Highlighted in context | `**touch base**` |