@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,106 @@
1
+ # 输出规则
2
+
3
+ > 本文件定义所有 LLM 输出的通用规则。生成内容时必须遵守这些规则。
4
+
5
+ ---
6
+
7
+ ## JSON 输出要求
8
+
9
+ ### 基本规则
10
+ - ⛔ **只输出合法 JSON** - 无 markdown 代码块,无 ```json 标记
11
+ - ⛔ **无多余文本** - 不要在 JSON 前后添加说明文字
12
+ - ⛔ **无注释** - JSON 中不允许 `//` 或 `/* */` 注释
13
+ - ✅ **必须通过 Schema 验证** - 符合 `templates/` 目录下的 JSON Schema
14
+
15
+ ### JSON 转义规则 (用于 bash 命令)
16
+ ```bash
17
+ # 单引号包裹
18
+ python3 -m scripts.cli.cli save_daily --content-type keypoint --content '{"key": "value"}'
19
+
20
+ # 转义内部单引号: ' → '\''
21
+ python3 -m scripts.cli.cli save_daily --content-type keypoint --content '{"title": "It'\''s a test"}'
22
+ ```
23
+
24
+ ---
25
+
26
+ ## Markdown 格式规则
27
+
28
+ ### 平台兼容性
29
+
30
+ | 格式 | 语法 | 飞书 | Discord | Telegram | Slack |
31
+ |------|------|------|---------|----------|-------|
32
+ | 粗体 | `**text**` | ✅ | ✅ | ✅ | ✅ |
33
+ | 斜体 | `*text*` | ✅ | ✅ | ✅ | ✅ |
34
+ | 链接 | `[text](url)` | ✅ | ✅ | ✅ | ✅ |
35
+ | 代码 | `` `code` `` | ✅ | ✅ | ✅ | ✅ |
36
+ | 删除线 | `~~text~~` | ❌ | ✅ | ✅ | ✅ |
37
+
38
+ ### 飞书兼容性特别说明
39
+ - **删除线**: 飞书不支持 `~~text~~` 语法
40
+ - **替代方案**: 直接使用「错误:xxx」而非删除线
41
+
42
+ ---
43
+
44
+ ## 标点符号规则
45
+
46
+ | 规则 | 正确示例 | 错误示例 |
47
+ |------|----------|----------|
48
+ | 陈述句以句号结尾 | `This is correct.` | `This is correct` |
49
+ | 问句以问号结尾 | `How are you?` | `How are you` |
50
+ | 避免连续标点 | `Great!` | `Great!!!` |
51
+ | 中英文标点不混用 | `Hello, 你好。` | `Hello,你好.` |
52
+
53
+ ---
54
+
55
+ ## 双语标签格式
56
+
57
+ ### 标准格式
58
+ ```
59
+ 中文 | English
60
+ ```
61
+
62
+ ### 示例
63
+ ```
64
+ 选择题 | Multiple Choice
65
+ 填空题 | Fill in the Blank
66
+ Chinglish 修正 | Fix the Chinglish
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Display 对象通用字段
72
+
73
+ 所有 `display` 对象应包含以下通用格式字段:
74
+
75
+ | 字段 | 描述 | 示例 |
76
+ |------|------|------|
77
+ | `type_emoji` | 类型图标 | `🔤` |
78
+ | `type_name` | 类型名称(双语) | `选择题 \| Multiple Choice` |
79
+ | `hint` | 提示(不泄露答案) | `💡 考虑上下文...` |
80
+ | `correct_feedback` | 正确反馈 | `✅ 正确!` |
81
+ | `wrong_feedback` | 错误反馈 | `❌ 再想想...` |
82
+ | `xp_display` | XP 显示 | `💎 +10 XP` |
83
+
84
+ ---
85
+
86
+ ## Emoji 使用规则
87
+
88
+ ### 通用原则
89
+ - ✅ 使用表情符号增加视觉效果
90
+ - ✅ 每个主要部分使用 emoji 作为视觉分隔
91
+ - ⛔ 不要过度使用,保持简洁
92
+ - ⛔ 不要在 JSON 字段名中使用 emoji
93
+
94
+ ### 常用 Emoji 参考
95
+ - 📝 文档/测验
96
+ - 💬 对话/聊天
97
+ - 💎 XP/奖励
98
+ - ✅ 正确/完成
99
+ - ❌ 错误
100
+ - 💡 提示
101
+ - 🎯 目标/要点
102
+ - 📅 日期
103
+ - 🏆 成就/徽章
104
+ - ⛔ 禁止/警告
105
+
106
+ 详细 Emoji 映射请参考 [display_guide.md](display_guide.md)。
@@ -0,0 +1,190 @@
1
+ # Quiz Generation Template
2
+
3
+ > Template for generating daily quizzes based on knowledge points.
4
+
5
+ **Related Files:**
6
+ - [shared_enums.md](shared_enums.md) - Quiz types, XP values, CEFR levels
7
+ - [output_rules.md](output_rules.md) - JSON output rules, markdown formatting
8
+
9
+ ---
10
+
11
+ ## Quiz Generation Prompt
12
+
13
+ ```markdown
14
+ Based on today's knowledge point, generate a 3-question quiz calibrated to user's CEFR level.
15
+
16
+ ## USER CONTEXT
17
+ - CEFR Level: {cefr_level} (A1=Beginner to C2=Proficient)
18
+
19
+ ## KNOWLEDGE POINT
20
+ {keypoint_json}
21
+
22
+ ## CEFR DIFFICULTY CALIBRATION
23
+
24
+ | Level | Question Characteristics |
25
+ |-------|-------------------------|
26
+ | A1-A2 | Simple recognition, obvious distractors, direct context matching |
27
+ | B1-B2 | Nuanced usage, subtle distractors, requires understanding context |
28
+ | C1-C2 | Complex scenarios, idiomatic variations, cultural nuance testing |
29
+
30
+ **For B1-B2 (most users):**
31
+ - Multiple choice: Distractors should be grammatically correct but contextually wrong
32
+ - Chinglish fix: Use subtle errors (preposition, article, word choice) not obvious mistakes
33
+ - Create NEW scenarios that differ from the keypoint examples
34
+
35
+ ## QUESTION TYPE REQUIREMENTS (3 questions total)
36
+ 1. **multiple_choice** (required): Test expression recognition - 10 XP
37
+ 2. **chinglish_fix** (required): Identify and correct Chinglish - 15 XP
38
+ 3. **fill_blank OR dialogue_completion** (random): Pick one randomly - 12 XP
39
+
40
+ ## QUESTION GUIDELINES
41
+
42
+ ### Multiple Choice (10 XP)
43
+ - 4 options (A, B, C, D)
44
+ - Only 1 correct answer
45
+ - **Distractors MUST be plausible** - grammatically correct but semantically wrong
46
+ - Test understanding of meaning or usage in a NEW context (not copied from keypoint)
47
+ - For B2+: Include one distractor that's "almost correct" to test nuance
48
+
49
+ ### Chinglish Fix (15 XP)
50
+ - Show a sentence with Chinglish expressions
51
+ - **Create a NEW sentence** - NOT the example from the keypoint
52
+ - For B2+: Use subtle errors (wrong preposition, article misuse, slight word order)
53
+ - Include explanation in the answer
54
+
55
+ ### Fill in the Blank (12 XP)
56
+ - Use "___" for the blank
57
+ - Provide word bank with 3 options
58
+ - **Create a NEW context/sentence** - NOT copied from keypoint
59
+ - Test the expression in a different situation
60
+
61
+ ### Dialogue Completion (12 XP)
62
+ - Show partial dialogue with NEW context
63
+ - Ask what should come next
64
+ - Test natural conversation flow
65
+
66
+ ## ⛔ CRITICAL PROHIBITIONS ⛔
67
+
68
+ 1. **NEVER copy questions directly from keypoint content**
69
+ - Create NEW scenarios and contexts
70
+ - Change the situation while testing the same expression
71
+
72
+ 2. **NEVER reveal the answer in hints or question text**
73
+ - Hint format: "💡 Think about what Americans say in this situation"
74
+ - FORBIDDEN: "💡 The answer is 'touch base'" or showing the phrase directly
75
+
76
+ 3. **NEVER make distractors obviously wrong**
77
+ - All 4 options should sound plausible
78
+ - For B2+: At least one distractor should be a common learner error
79
+
80
+ ## STRICT RULES
81
+ > **See [output_rules.md](output_rules.md) for complete JSON/Markdown formatting rules.**
82
+
83
+ 1. All questions must relate to today's knowledge point
84
+ 2. **Difficulty MUST match CEFR level** - harder for B2+ users
85
+ 3. Include encouraging feedback in display fields
86
+ 4. Total XP should be around 35-40
87
+ 5. **Use NEW contexts** - never copy-paste from keypoint examples
88
+ ```
89
+
90
+ ---
91
+
92
+ ## Output Schema
93
+
94
+ > **CRITICAL:** Display fields must NOT reveal answers before user responds.
95
+
96
+ ```json
97
+ {
98
+ "_meta": {
99
+ "prompt_version": "quiz_gen_v1.2"
100
+ },
101
+ "quiz_date": "{today_date}",
102
+ "keypoint_fingerprint": "{fingerprint}",
103
+ "cefr_level": "{cefr_level}",
104
+ "questions": [
105
+ {
106
+ "id": 1,
107
+ "type": "multiple_choice",
108
+ "question": "The question text - MUST be a NEW context, not copied from keypoint",
109
+ "context": "NEW scenario description",
110
+ "options": ["A. ...", "B. ...", "C. ...", "D. ..."],
111
+ "correct_answer": "B",
112
+ "explanation": "Why this is correct...",
113
+ "xp_value": 10,
114
+ "display": {
115
+ "type_emoji": "🔤",
116
+ "type_name": "选择题 | Multiple Choice",
117
+ "question_formatted": "💬 {question}",
118
+ "context_formatted": "📱 {context}",
119
+ "options_formatted": ["⬜ A. ...", "⬜ B. ...", "⬜ C. ...", "⬜ D. ..."],
120
+ "hint": "💡 Think about the context - which fits naturally?",
121
+ "correct_feedback": "✅ Correct! **{key_phrase}** = {meaning}",
122
+ "wrong_feedback": "❌ Not quite. The answer was **{correct_answer}**. {explanation}",
123
+ "xp_display": "💎 +10 XP"
124
+ }
125
+ },
126
+ {
127
+ "id": 2,
128
+ "type": "chinglish_fix",
129
+ "question": "Fix this sentence - MUST be NEW sentence, not from keypoint",
130
+ "chinglish_sentence": "A NEW sentence with Chinglish error...",
131
+ "correct_answer": "The corrected version...",
132
+ "explanation": "Why the original was wrong...",
133
+ "xp_value": 15,
134
+ "display": {
135
+ "type_emoji": "🔧",
136
+ "type_name": "Chinglish 修正 | Fix the Chinglish",
137
+ "question_formatted": "🔧 What's wrong with this sentence?",
138
+ "sentence_formatted": "📝 \"{chinglish_sentence}\"",
139
+ "hint": "💡 How would an American say this naturally?",
140
+ "correct_feedback": "✅ Fixed! **{correct_phrase}** sounds much more natural!",
141
+ "wrong_feedback": "❌ Better: **{correct_sentence}**\n💡 {explanation}",
142
+ "xp_display": "💎 +15 XP"
143
+ }
144
+ },
145
+ {
146
+ "id": 3,
147
+ "type": "fill_blank",
148
+ "question": "Complete the sentence - MUST be NEW context",
149
+ "context": "NEW dialogue or situation with ___ blank",
150
+ "word_bank": ["phrase1", "phrase2", "phrase3"],
151
+ "correct_answer": "phrase1",
152
+ "explanation": "...",
153
+ "xp_value": 12,
154
+ "display": {
155
+ "type_emoji": "✏️",
156
+ "type_name": "填空题 | Fill in the Blank",
157
+ "question_formatted": "✏️ Fill in the blank:",
158
+ "context_formatted": "💬 {context_with_blank}",
159
+ "word_bank_formatted": "📦 Options: [ {opt1} | {opt2} | {opt3} ]",
160
+ "hint": "💡 Consider the formality and context.",
161
+ "correct_feedback": "✅ Perfect! **{answer}** fits perfectly here!",
162
+ "wrong_feedback": "❌ The answer was **{correct_answer}**. {explanation}",
163
+ "xp_display": "💎 +12 XP"
164
+ }
165
+ }
166
+ ],
167
+ "total_xp": 37,
168
+ "passing_score": 70,
169
+ "display": {
170
+ "header": "📝 今日测验 | Daily Quiz",
171
+ "date": "📅 {quiz_date}",
172
+ "difficulty": "📊 Level: **{cefr_level}**",
173
+ "topic": "🏷️ Topic: **{topic_name}**",
174
+ "instructions": "🎯 3道小题,答对2道就过关!3 questions, get 2 right to pass!",
175
+ "progress_bar": "⬜⬜⬜ 0/3 questions",
176
+ "xp_summary": "💎 Total XP: {total_xp} | 🏆 Pass: 2/3 correct",
177
+ "footer": "───────────────────\n💪 Good luck! 加油! 🚀"
178
+ }
179
+ }
180
+ ```
181
+
182
+ **Note:** Removed `key_phrase_summary` from display - it reveals the answer before quiz starts!
183
+
184
+ ---
185
+
186
+ ## XP Values Summary
187
+
188
+ > See [shared_enums.md](shared_enums.md#quiz-question-types-题型) for full quiz type definitions.
189
+
190
+ **Daily Quiz:** 3 questions, ~37 XP, pass with 2/3 correct
@@ -0,0 +1,339 @@
1
+ # Response Templates
2
+
3
+ > Templates for various response scenarios in the eng-lang-tutor skill.
4
+
5
+ **Related Files:**
6
+ - [shared_enums.md](shared_enums.md) - Level names, badges, quiz types
7
+ - [output_rules.md](output_rules.md) - JSON output rules, markdown formatting
8
+ - [display_guide.md](display_guide.md) - Emoji and formatting guidelines
9
+
10
+ ---
11
+
12
+ ## 1. Already Completed Responses
13
+
14
+ ```json
15
+ {
16
+ "quiz_already_done": {
17
+ "display": {
18
+ "title": "✅ Already Completed!",
19
+ "message": "You've already finished today's quiz. Great job! 🎉",
20
+ "stats": "Your score: {score}/{total} | XP earned: {xp}",
21
+ "next_quiz": "Come back tomorrow at 10:45 PM for a new quiz!",
22
+ "alternative": "💡 Want to review? Say **errors** to see your wrong answers."
23
+ }
24
+ }
25
+ }
26
+ ```
27
+
28
+ ---
29
+
30
+ ## 2. Not Available Responses
31
+
32
+ ```json
33
+ {
34
+ "keypoint_not_found": {
35
+ "display": {
36
+ "title": "📅 No Keypoint Found",
37
+ "message": "No knowledge point exists for {date}.",
38
+ "hint": "Try **keypoint today** for today's content.",
39
+ "history": "Or say **keypoint history** to see recent keypoints."
40
+ }
41
+ }
42
+ }
43
+ ```
44
+
45
+ ---
46
+
47
+ ## 2.5. Quiz Request Flow (CRITICAL)
48
+
49
+ > **NEVER tell user "will generate later" - ALWAYS generate immediately when user requests quiz.**
50
+
51
+ ```
52
+ When user requests quiz:
53
+ 1. Check if quiz already completed today (completion_status.quiz_completed_date == today)
54
+ → YES: Show "Already completed" message
55
+ → NO: Continue to step 2
56
+
57
+ 2. Check if keypoint.json exists for today
58
+ → NO: IMMEDIATELY generate keypoint via LLM (do NOT say "will notify later")
59
+ Save keypoint with generated=true
60
+ → YES: Continue to step 3
61
+
62
+ 3. Check if quiz.json exists and quiz.generated == true
63
+ → NO: IMMEDIATELY generate quiz via LLM based on keypoint
64
+ Save quiz with generated=true
65
+ → YES: Load existing quiz
66
+
67
+ 4. Present quiz questions to user in ONE response
68
+ ```
69
+
70
+ **FORBIDDEN responses:**
71
+ - ❌ "今天还没有生成知识点,稍后会为您生成并通知您"
72
+ - ❌ "Quiz will be available later"
73
+ - ❌ "Please wait for the scheduled push"
74
+
75
+ **REQUIRED behavior:**
76
+ - ✅ Generate keypoint immediately via LLM if missing
77
+ - ✅ Generate quiz immediately via LLM
78
+ - ✅ Present quiz in the same response
79
+
80
+ ---
81
+
82
+ ## 3. Keypoint History Response
83
+
84
+ **When user says:** `keypoint history`, `知识点 历史`, `昨天`, `yesterday`
85
+
86
+ **Logic:**
87
+ 1. Scan `~/.openclaw/state/eng-lang-tutor/daily/` directory for all `YYYY-MM-DD/keypoint.json` files
88
+ 2. Sort by date descending (most recent first)
89
+ 3. Extract `display.title` or `topic` from each keypoint
90
+
91
+ **Empty History Response:**
92
+ ```markdown
93
+ 📚 **知识点历史记录**
94
+
95
+ 暂无历史记录。从今天开始学习吧!
96
+
97
+ 💡 输入 **keypoint** 或 **知识点** 获取今日内容
98
+ ```
99
+
100
+ **With History Response:**
101
+ ```markdown
102
+ 📚 **知识点历史记录**
103
+
104
+ | 日期 | 主题 |
105
+ |------|------|
106
+ | 2026-02-21 | 🏢 Touch Base - 工作沟通 |
107
+ | 2026-02-20 | 🎮 GG - 游戏用语 |
108
+ | 2026-02-19 | 🗣️ Gonna/Wanna - 口语缩写 |
109
+
110
+ 💡 输入 **keypoint 日期** 查看详情,如 `keypoint 2026-02-20`
111
+ ```
112
+
113
+ ---
114
+
115
+ ## 4. Keypoint Display Template
116
+
117
+ > IMPORTANT: Use `**text**` for bold. Never use `~~strikethrough~~`. Output Markdown text directly, NOT JSON.
118
+
119
+ **Assembly Flow:**
120
+
121
+ ```markdown
122
+ {title}
123
+
124
+ | 主题 | **{topic_name}** |
125
+ |------|------------------|
126
+ | 正式度 | **{formality}** |
127
+
128
+ ───────────────────
129
+ {scene_intro}
130
+
131
+ {scene_text}
132
+
133
+ ───────────────────
134
+ {expressions_title}
135
+
136
+ {for each item in expressions_formatted:
137
+ {emoji} {phrase}
138
+ {pronunciation}
139
+ {usage}
140
+ }
141
+
142
+ ───────────────────
143
+ {alternatives_title}
144
+
145
+ {alternatives_formatted}
146
+
147
+ ───────────────────
148
+ {chinglish_title}
149
+
150
+ {chinglish_formatted}
151
+
152
+ ───────────────────
153
+ {examples_title}
154
+
155
+ {for each item in examples_formatted:
156
+ {situation_emoji} {situation}
157
+ {dialogue}
158
+ }
159
+
160
+ ───────────────────
161
+ {extended_title}
162
+
163
+ {extended_formatted}
164
+
165
+ ───────────────────
166
+ {references_title}
167
+
168
+ {references_formatted}
169
+
170
+ ───────────────────
171
+ {footer}
172
+ ```
173
+
174
+ ---
175
+
176
+ ## 5. Stats Display Template
177
+
178
+ ```markdown
179
+ 📊 **Your Learning Progress**
180
+
181
+ • 等级: **{level}** ({level_name})
182
+ • XP: **{current_xp}** / {next_level_xp} (**{progress}%**)
183
+ • 连胜: **{streak}** 天 (倍数: **{multiplier}x**)
184
+ • 正确率: **{correct_rate}%**
185
+ • 徽章: **{badges_count}**/6
186
+ • 宝石: **{gems}**
187
+
188
+ ───────────────────
189
+ Keep it up! 💪
190
+ ```
191
+
192
+ > See [shared_enums.md](shared_enums.md#activity-levels-活跃等级) for level names.
193
+
194
+ **Multiplier Calculation:** `1.0 + (streak * 0.05)`, max 2.0x
195
+
196
+ ---
197
+
198
+ ## 6. Config Display Template
199
+
200
+ ```markdown
201
+ ⚙️ **Your Settings**
202
+
203
+ • CEFR 等级: **{cefr_level}**
204
+ • 主题偏好: **{topics_list}**
205
+ • 导师风格: **{tutor_style}**
206
+ • 口语占比: **{oral_ratio}%**
207
+ • 知识点推送: **{keypoint_time}**
208
+ • Quiz 推送: **{quiz_time}**
209
+
210
+ ───────────────────
211
+ 💡 Say **set level B2** to change your level
212
+ ```
213
+
214
+ ---
215
+
216
+ ## 7. Errors Display Template (Paginated)
217
+
218
+ ```markdown
219
+ 📓 **Error Notebook**
220
+
221
+ 📊 统计: **{total}** 条错题 (未复习: **{unreviewed}**)
222
+
223
+ ❌ 最近 **5** 条:
224
+
225
+ **{date_1}**
226
+ Q: {question_1}
227
+ Your answer: {user_answer_1}
228
+ ✅ Correct: **{correct_answer_1}**
229
+
230
+ **{date_2}**
231
+ Q: {question_2}
232
+ Your answer: {user_answer_2}
233
+ ✅ Correct: **{correct_answer_2}**
234
+
235
+ [显示 5 条,第 1/{total_pages} 页]
236
+
237
+ ───────────────────
238
+ 📄 输入 **"错题本 更多"** 查看下5条
239
+ 📄 输入 **"错题本 2026-02"** 查看特定月份
240
+ 📄 输入 **"错题本 随机5"** 随机复习5条
241
+ 📄 输入 **"错题本 统计"** 查看完整统计
242
+ 📄 输入 **"错题本 复习"** 开始错题复习
243
+ ```
244
+
245
+ **Pagination Commands:**
246
+ - `errors` / `错题本` → Show recent 5 errors
247
+ - `errors more` / `错题本 更多` → Next 5 errors
248
+ - `errors page N` → Go to page N
249
+ - `errors 2026-02` → Filter by month
250
+ - `errors random 5` → Random 5 for review
251
+ - `errors stats` → Show statistics only
252
+ - `errors review` → Start interactive review
253
+
254
+ ### Error Review Session Flow
255
+
256
+ When user starts `errors review`:
257
+
258
+ **1. Load Errors**
259
+ - Fetch unreviewed errors from `error_notebook` (max 5 at a time)
260
+ - Skip already reviewed errors (`reviewed: true`)
261
+
262
+ **2. Present Question**
263
+ ```markdown
264
+ 🔄 **Error Review** ({current}/{total})
265
+
266
+ ❌ 原题: {question}
267
+ 📝 你的答案: {user_answer}
268
+ ✅ 正确答案: **{correct_answer}**
269
+
270
+ 💡 {explanation}
271
+
272
+ ───────────────────
273
+ 回答回忆: 你选择了 **{user_answer}**
274
+ 现在你还记得为什么吗?输入 **记得** 或 **忘了**
275
+ ```
276
+
277
+ **3. User Response**
278
+ - If "记得" / "remember": Mark as reviewed, +5 XP
279
+ - If "忘了" / "forgot": Keep in notebook, show explanation again
280
+
281
+ **4. State Update**
282
+ - Update `error_notebook[].reviewed` to `true` for remembered items
283
+ - Increment `reviewed_count` for badge tracking
284
+ - Log event: `error_reviewed`
285
+
286
+ **5. Completion**
287
+ ```markdown
288
+ 🎉 **Review Complete!**
289
+
290
+ 📊 本次复习: **{reviewed}** 题
291
+ 💎 获得: **+{xp} XP**
292
+
293
+ {if all reviewed:}
294
+ ✨ 恭喜!错题本已清空!获得徽章: **Error Slayer** (清除30个错题)
295
+ {else:}
296
+ 📓 还剩 **{remaining}** 条错题待复习
297
+
298
+ ───────────────────
299
+ 💪 继续加油!输入 **errors review** 再来一轮
300
+ ```
301
+
302
+ ---
303
+
304
+ ## 8. Quiz Result Display Template
305
+
306
+ ```markdown
307
+ 📊 **Quiz Results**
308
+
309
+ • 分数: **{correct}/{total}** (**{accuracy}%**)
310
+ • 状态: {status_emoji} {status_text}
311
+ • XP 获得: **+{total_xp} XP**
312
+ • 连胜: **{old_streak}** → **{new_streak}** 天
313
+ • 总 XP: **{total_xp_earned}**
314
+
315
+ 💎 XP 明细:
316
+ • Base: **{base_xp} XP**
317
+ • Streak Bonus: **{multiplier}x** ({streak} day streak)
318
+ {perfect_bonus}
319
+
320
+ ───────────────────
321
+ 📝 Come back tomorrow for a new quiz!
322
+ ```
323
+
324
+ **Variables:**
325
+ - `{status_emoji}`: ✅ for passed, ❌ for failed
326
+ - `{status_text}`: "Passed! Great job! 🎉" or "Keep trying! 💪"
327
+ - `{perfect_bonus}`: "• Perfect Bonus: **+20 XP**" (only if 100% correct)
328
+
329
+ ---
330
+
331
+ ## 9. Output Format Rules
332
+
333
+ > See [output_rules.md](output_rules.md) for complete formatting rules.
334
+
335
+ **Quick Reference:**
336
+ - **Bold syntax**: Use `**text**` for bold
337
+ - **Never use** `~~strikethrough~~` - use ❌ emoji instead
338
+ - **Emojis**: Include at the start of each section
339
+ - **Punctuation**: End sentences properly (`.` or `?` or `!`)