American English Tutor
Overview
Teaches authentic American English expressions, avoiding Chinglish patterns. Delivers personalized content via daily knowledge points, quizzes, and weekly exercises. Includes Duolingo-style gamification (XP, streaks, levels, badges, leagues).
Core Workflow
- Daily Knowledge Point Generation
Input: state.json (user preferences, CEFR level, recent topics) Process:
-
Load user preferences from state.json
-
Load recent topic fingerprints (14 days) for deduplication
-
Select topic based on user preference weights
-
Generate knowledge point via LLM (pure JSON output)
-
Validate JSON schema
-
Save to daily/YYYY-MM-DD/keypoint.json
-
Update state.json recent_topics
-
Append event to logs/events_YYYY-MM.jsonl Output: keypoint.json
-
Quiz Generation
Input: keypoint.json Process:
-
Read today's keypoint.json
-
Generate 3 questions (fixed pattern):
- 1 multiple_choice (10 XP)
- 1 chinglish_fix (15 XP)
- 1 fill_blank OR dialogue_completion (12 XP, random)
-
Save to daily/YYYY-MM-DD/quiz.json (with answers) Output: quiz.json (~37 XP total)
-
Answer Evaluation
Input: quiz.json, user_answers.json Process:
-
Compare user answers with correct answers
-
Calculate XP (base + streak multiplier + perfect bonus)
-
Update state.json (XP, streak, level, badges)
-
Record wrong answers to error_notebook Output: results.json, updated state.json
-
Weekly Exercise (Sundays)
Input: This week's keypoint.json files Process:
- Aggregate week's knowledge points
- Generate 5 questions (mixed types):
- 2 multiple_choice (20 XP)
- 1 chinglish_fix (15 XP)
- 1 fill_blank (12 XP)
- 1 dialogue_completion (15 XP)
- Save to daily/YYYY-MM-DD/weekly.json
- After scoring, update league rankings Output: weekly.json (~62 XP total)
Quiz Types
Type Description XP Value Daily Quiz Weekly
multiple_choice Select correct expression from 4 options 10 1 (required) 2
chinglish_fix Identify and correct Chinglish expression 15 1 (required) 1
fill_blank Complete dialogue with missing expression 12 0-1 (random) 1
dialogue_completion Choose appropriate response in context 15 0-1 (random) 1
Daily Quiz Pattern: 3 questions, ~37 XP, pass with 2/3 correct Weekly Exercise: 5 questions, ~62 XP, pass with 3/5 correct
Gamification System
XP & Levels
This system has two independent level systems:
-
Ability Level (CEFR): A1-C2, determines content difficulty (language proficiency)
-
Activity Level (Level): 1-20, measures engagement depth (usage progression)
Activity Level Stages (Journey):
-
Level 1-5 (Starter/启程者): 0-350 XP
-
Level 6-10 (Traveler/行路人): 550-2000 XP
-
Level 11-15 (Explorer/探索者): 2600-6000 XP
-
Level 16-20 (Pioneer/开拓者): 7200-15000 XP
Streak System
-
Consecutive days of study builds streak
-
Streak broken if miss a day (unless using streak freeze)
-
Streak multiplier: 1.0 + (streak * 0.05), max 2.0x
-
Streak freeze costs 50 gems
Leagues (Weekly)
- Bronze (0+ XP) -> Silver (100+ XP) -> Gold (200+ XP) -> Platinum (350+ XP) -> Diamond (500+ XP)
Badges
-
First Steps: Complete first quiz (+10 gems)
-
Week Warrior: 7-day streak (+25 gems)
-
Month Master: 30-day streak (+100 gems)
-
Perfect 10: 10 perfect quizzes (+50 gems)
-
Vocab Hunter: Learn 100 expressions (+75 gems)
-
Error Slayer: Clear 30 errors (+30 gems)
Key Scripts
Script Purpose
state_manager.py State persistence, event logging
quiz_generator.py Generate quiz questions (4 types)
scorer.py Answer evaluation, XP calculation
gamification.py Streak/level/badge/league logic
dedup.py 14-day content deduplication
Core Principles
-
Always output valid JSON - No markdown, no extra text
-
Focus on "How Americans say it" - NOT translation
-
Every knowledge point must include:
-
Scene context
-
Alternative expressions
-
Chinglish trap + correction
-
14-day deduplication - No repeated topics or expressions
-
Topic fingerprints - Use unique identifiers for deduplication
File Structure
data/ state.json # Core state (streak/xp/preferences) logs/ events_2026-02.jsonl # Monthly event log daily/ 2026-02-20/ keypoint.json # Today's knowledge point quiz.json # Today's quiz weekly.json # Weekly exercise (Sundays) user_answers.json # User's answers
JSON Schemas
See templates/ directory:
-
state_schema.json
-
keypoint_schema.json
-
quiz_schema.json
Resource References
See references/ directory:
- resources.md - Themed English learning resources (TV shows, news, gaming, sports, workplace, daily life)
See templates/ directory:
- prompt_templates.md - LLM prompt templates for content generation
Examples
See examples/ directory for sample outputs.
User Commands
The bot recognizes these natural language commands:
Initialization
Command Aliases Description
start
begin , 开始 , 初始化 , 你好
Start the onboarding process
Learning Content
Command Aliases Description
keypoint
知识点 , 今天 , today
View today's knowledge point
keypoint history
知识点 历史 , 昨天 , yesterday
View historical keypoints
quiz
测验 , test , 测试
Take today's quiz (once per day)
weekly
周周练 , 本周练习
Take weekly exercise (once per week)
Progress & Stats
Command Aliases Description
stats
进度 , 统计 , level , XP
View learning progress
errors
错题本 , mistakes
View error notebook (recent 5)
errors more
错题本 更多
Next 5 errors
errors 2026-02
错题本 2026-02
Filter by month
errors random 5
错题本 随机5
Random 5 for review
errors stats
错题本 统计
Show error statistics
errors review
错题本 复习 , 错题复习
Start error review session (5 questions)
Settings
Command Aliases Description
config
设置 , preferences
View current settings
set level B2
设置等级 B2
Change CEFR level
set style professional
设置风格 专业
Change tutor style
schedule
时间表 , 推送时间
View/change schedule
Help
Command Aliases Description
help
帮助 , 怎么用
Show available commands
Initialization Flow
New users go through a 5-step onboarding process:
Step 0: Welcome → User replies "start" Step 1: Select CEFR Level (A1-C2) Step 2: Select Topic Interests (movies/news/gaming/sports/workplace/social/daily_life) Step 3: Select Tutor Style (humorous/rigorous/casual/professional) Step 4: Select Oral/Written Ratio (0-100% oral) Step 5: Confirm Configuration → Set initialized=true
State Fields:
-
initialized : Boolean - Whether user completed onboarding
-
onboarding_step : Integer (0-5) - Current step in onboarding
Response Scenarios
Quiz Already Completed
User: "quiz" Bot checks: completion_status.quiz_completed_date == today? → YES: "You've already completed today's quiz! 🎉 Score: X/Y" → NO: Load/generate quiz and present questions
Weekly Already Completed
User: "weekly" Bot checks: completion_status.weekly_completed_week_start == this week's Monday? → YES: "You've already completed this week's exercise! 🎉" → NO: Load/generate weekly and present questions
Keypoint Query
User: "keypoint" or "知识点" or Cron Push Bot checks: Does keypoint.json exist for today? → YES: Read display object, assemble into Markdown, output → NO: Generate new keypoint, then display → Record view in keypoint_view_history
Display Fields (from keypoint.json display object):
Field Description
title
Main title with emoji
topic_tag
Topic label
formality_tag
Formality level
scene_text
Scene description
expressions_formatted
Array of formatted expressions
alternatives_formatted
Bullet list of alternatives
chinglish_formatted
Wrong/Correct comparison
examples_formatted
Array of dialogue examples
extended_formatted
Extended learning content
references_formatted
Reference links
footer
Date and footer info
IMPORTANT: Output assembled Markdown text directly, NOT JSON. See templates/prompt_templates.md Section 10.3 for full assembly template.
Historical Keypoint
User: "keypoint 昨天" or "keypoint 2026-02-19" Bot checks: Does keypoint.json exist for that date? → YES: Display → NO: "No keypoint found for that date. Try 'keypoint today'."
Config Display
User: "config" or "设置" Bot reads: state.json preferences Output: Card format with formatted text (see Output Format below)
Stats Display
User: "stats" or "进度" Bot reads: state.json user + progress Output: Card format with emoji and formatted text
Response Output Format
IMPORTANT: All responses use platform-agnostic Markdown format. See templates/prompt_templates.md Section 10 for detailed formatting rules and examples/ for sample outputs.
Quick Reference
-
Format: Standard Markdown (compatible with Feishu, Discord, Telegram, Slack)
-
Bold: text
-
Links: text
-
Emojis: Use liberally for visual sections
-
Dividers: ───────────────────
Feishu Card Rendering
For Feishu channel, OpenClaw/Moltbot handles Markdown-to-Card conversion automatically when configured properly.
Feishu Message Types:
Type msg_type Description
Text text
Plain text only
Rich Text post
Formatted text
Interactive Card interactive
Full card with components
Configuration for Card Rendering:
{ "streaming": true, "blockStreaming": true }
When these options are enabled, OpenClaw/Moltbot will automatically convert structured Markdown (tables, formatted sections) into Feishu interactive cards.
Best Practices for Feishu:
-
Avoid
strikethrough -
Not supported in Feishu cards; use ❌ emoji instead
-
Use structured Markdown - Tables and formatted sections enable better card rendering
-
Enable streaming - streaming: true
- blockStreaming: true for real-time card updates
Response Templates
All response templates are documented in templates/prompt_templates.md Section 10:
Template Section Description
Keypoint Display 10.3 Daily knowledge point output
Stats Display 10.4 Learning progress stats
Config Display 10.5 User settings display
Errors Display 10.6 Error notebook (paginated)
Error Review 10.7 Error review session flow
Quiz Result 10.8 Quiz completion results
Weekly Result 10.9 Weekly exercise results
Completion Tracking
State Fields
{ "completion_status": { "quiz_completed_date": "2026-02-20", "weekly_completed_week_start": "2026-02-16", "keypoint_view_history": [ {"date": "2026-02-20", "viewed_at": "2026-02-20T06:45:00"} ] } }
Rules
-
Quiz: Can only take once per day (resets at midnight)
-
Weekly: Can only take once per week (resets on Monday)
-
Keypoint: Can view multiple times (including historical pushed keypoints)
Cron Configuration
Default Schedule (UTC+8 / Asia/Shanghai)
Task Default Time Description
Keypoint Push 06:45 Daily knowledge point
Quiz Push 22:45 Daily quiz
Weekly Push Sunday 13:30 Weekly exercise
Weekly Reset Monday 00:00 Reset weekly stats
Crontab Template
/etc/cron.d/eng-lang-tutor
CRON_TZ=Asia/Shanghai
6:45 AM - Keypoint push
45 6 * * * openclaw agent --channel discord --message "☕ Good morning!" --agent eng-lang-tutor
10:45 PM - Quiz push
45 22 * * * openclaw agent --channel discord --message "🌙 Quiz time!" --agent eng-lang-tutor
1:30 PM Sunday - Weekly push
30 13 * * 0 openclaw agent --channel discord --message "📅 Weekly exercise!" --agent eng-lang-tutor
Monday midnight - Weekly reset
0 0 * * 1 cd ~/.openclaw/skills/eng-lang-tutor && python3 scripts/cron_push.py --task reset_weekly
User-Customizable Schedule
Users can customize their schedule via commands:
set schedule keypoint 7:00 set schedule quiz 21:00 set schedule weekly sunday 14:00
Stored in state.json :
{ "schedule": { "keypoint_time": "07:00", "quiz_time": "21:00", "weekly_time": "14:00", "weekly_day": 0, "timezone": "Asia/Shanghai" } }
Cron Failure Handling (Lazy Reset)
If the weekly reset cron job fails, the system automatically recovers:
Any cron task (keypoint/quiz/weekly) runs ↓ Call ensure_weekly_reset(state) ↓ Check: last_weekly_reset_week == this week's Monday? ↓ YES → Skip reset NO → Execute weekly reset (idempotent) ↓ Continue with original task
Additional Scripts
Script Purpose
command_parser.py Parse user messages to determine intent
cron_push.py Handle scheduled content generation