@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.
- package/.claude/settings.local.json +22 -0
- package/.gitignore +32 -0
- package/CHANGELOG.md +37 -0
- package/CLAUDE.md +275 -0
- package/README.md +369 -0
- package/SKILL.md +613 -0
- package/bin/eng-lang-tutor.js +177 -0
- package/docs/OPENCLAW_DEPLOYMENT.md +241 -0
- package/examples/sample_keypoint_a1.json +112 -0
- package/examples/sample_keypoint_a2.json +124 -0
- package/examples/sample_keypoint_b1.json +135 -0
- package/examples/sample_keypoint_b2.json +137 -0
- package/examples/sample_keypoint_c1.json +134 -0
- package/examples/sample_keypoint_c2.json +141 -0
- package/examples/sample_quiz_a1.json +94 -0
- package/examples/sample_quiz_a2.json +94 -0
- package/examples/sample_quiz_b1.json +92 -0
- package/examples/sample_quiz_b2.json +94 -0
- package/examples/sample_quiz_c1.json +94 -0
- package/examples/sample_quiz_c2.json +104 -0
- package/package.json +41 -0
- package/references/resources.md +292 -0
- package/requirements.txt +16 -0
- package/scripts/__init__.py +28 -0
- package/scripts/audio/__init__.py +23 -0
- package/scripts/audio/composer.py +367 -0
- package/scripts/audio/converter.py +331 -0
- package/scripts/audio/feishu_voice.py +404 -0
- package/scripts/audio/tts/__init__.py +30 -0
- package/scripts/audio/tts/base.py +166 -0
- package/scripts/audio/tts/manager.py +306 -0
- package/scripts/audio/tts/providers/__init__.py +12 -0
- package/scripts/audio/tts/providers/edge.py +111 -0
- package/scripts/audio/tts/providers/xunfei.py +205 -0
- package/scripts/audio/utils.py +63 -0
- package/scripts/cli/__init__.py +7 -0
- package/scripts/cli/cli.py +229 -0
- package/scripts/cli/command_parser.py +336 -0
- package/scripts/core/__init__.py +30 -0
- package/scripts/core/constants.py +125 -0
- package/scripts/core/error_notebook.py +308 -0
- package/scripts/core/gamification.py +405 -0
- package/scripts/core/scorer.py +295 -0
- package/scripts/core/state_manager.py +814 -0
- package/scripts/eng-lang-tutor +16 -0
- package/scripts/scheduling/__init__.py +6 -0
- package/scripts/scheduling/cron_push.py +229 -0
- package/scripts/utils/__init__.py +12 -0
- package/scripts/utils/dedup.py +331 -0
- package/scripts/utils/helpers.py +82 -0
- package/templates/keypoint_schema.json +420 -0
- package/templates/prompt_templates.md +73 -0
- package/templates/prompts/display_guide.md +106 -0
- package/templates/prompts/initialization.md +350 -0
- package/templates/prompts/keypoint_generation.md +272 -0
- package/templates/prompts/output_rules.md +106 -0
- package/templates/prompts/quiz_generation.md +190 -0
- package/templates/prompts/responses.md +339 -0
- package/templates/prompts/shared_enums.md +252 -0
- package/templates/quiz_schema.json +214 -0
- 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 `!`)
|