eng-lang-tutor

地道美式英语导师 - 提供每日知识点、Quiz测验等学习内容。支持游戏化学习(XP/连胜/等级/徽章)。触发场景:学习英语、英语知识点、Quiz、错题本、学习进度。被 cron job 调用以实现定期内容推送。

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "eng-lang-tutor" with this command: npx skills add rookiestar/skills/rookiestar-skills-eng-lang-tutor

American English Tutor

Overview

Teaches authentic American English expressions, avoiding Chinglish patterns. Delivers personalized content via daily knowledge points and quizzes. Includes Duolingo-style gamification (XP, streaks, levels, badges).

Core Workflow

0. Initialization Guard Check

⛔ BEFORE generating any content (keypoint/quiz), check initialized status:

If state.initialized == false:
  1. Show friendly message: "看起来你还没有完成初始化配置,让我帮你快速设置一下吧!"
  2. Automatically start onboarding from Step 1/7
  3. DO NOT proceed with content generation until onboarding completes

If state.initialized == true:
  Proceed with normal workflow below

1. Daily Knowledge Point Generation

Input: state.json (user preferences, CEFR level, recent topics)
Process:
  1. Load user preferences from state.json
  2. Load recent topic fingerprints (14 days) for deduplication
  3. Select topic based on user preference weights
  4. Generate knowledge point via LLM (pure JSON output)
  5. Validate JSON schema
  6. Save to daily/YYYY-MM-DD/keypoint.json
  7. Update state.json recent_topics
  8. Append event to logs/events_YYYY-MM.jsonl
Output: keypoint.json

2. Quiz Generation

Input: keypoint.json
Process:
  1. Read today's keypoint.json
  2. Generate 3 questions (fixed pattern):
     - 1 multiple_choice (10 XP)
     - 1 chinglish_fix (15 XP)
     - 1 fill_blank OR dialogue_completion (12 XP, random)
  3. Save to daily/YYYY-MM-DD/quiz.json (with answers)
Output: quiz.json (~37 XP total)

3. Answer Evaluation

Input: quiz.json, user_answers.json
Process:
  1. Compare user answers with correct answers
  2. Calculate XP (base + streak multiplier + perfect bonus)
  3. Update state.json (XP, streak, level, badges)
  4. Record wrong answers to error_notebook
Output: results.json, updated state.json

Quiz Types

See templates/prompts/shared_enums.md for full definitions.

TypeXPDaily
multiple_choice101 (required)
chinglish_fix151 (required)
fill_blank / dialogue_completion120-1 (random)

Daily Quiz: 3 questions, ~37 XP, pass with 2/3 correct

Gamification System

XP & Levels

This system has two independent level systems:

  • Ability Level (CEFR): A1-C2, determines content difficulty
  • Activity Level (Level): 1-20, measures engagement depth

See templates/prompts/shared_enums.md for level stages and badge definitions.

Streak System

  • Consecutive days of study builds streak
  • Streak multiplier: 1.0 + (streak * 0.05), max 2.0x
  • Streak freeze costs 50 gems

Key Scripts

ScriptPurpose
core/state_manager.pyState persistence, event logging, error notebook
core/error_notebook.pyError notebook management
core/scorer.pyAnswer evaluation, XP calculation
core/gamification.pyStreak/level/badge logic
core/constants.pyShared constants (level thresholds, level names)
cli/cli.pyCLI entry point for state management
cli/command_parser.pyNatural language command parsing
scheduling/cron_push.pyScheduled content push (keypoint/quiz placeholders)
utils/dedup.py14-day content deduplication
utils/helpers.pyUtility functions (safe divide, deep merge)
audio/Audio generation (TTS, composition, conversion, Feishu)

CLI Commands

These bash commands are used by the Agent to execute operations. Data is stored in ~/.openclaw/state/eng-lang-tutor/ by default. Do NOT specify --data-dir unless using a custom location.

Content Management

# Save daily content (keypoint/quiz)
python3 -m scripts.cli.cli save_daily --content-type keypoint --content '<JSON>'

# Record keypoint view
python3 -m scripts.cli.cli record_view [--date YYYY-MM-DD]

Stats & Config

# Display learning progress
python3 -m scripts.cli.cli stats

# Display current configuration
python3 -m scripts.cli.cli config

# Update configuration
python3 -m scripts.cli.cli config --cefr B2
python3 -m scripts.cli.cli config --style professional
python3 -m scripts.cli.cli config --oral-ratio 80

Error Notebook

# List errors (paginated)
python3 -m scripts.cli.cli errors [--page 1] [--per-page 5] [--month YYYY-MM]

# Get random errors for review
python3 -m scripts.cli.cli errors --random 5

# Get error statistics
python3 -m scripts.cli.cli errors --stats

# Get errors for review session
python3 -m scripts.cli.cli errors --review 5

Schedule

# Display current schedule
python3 -m scripts.cli.cli schedule

# Update schedule (quiz_time must be later than keypoint_time)
python3 -m scripts.cli.cli schedule --keypoint-time 07:00 --quiz-time 21:00

Core Principles

See templates/prompts/keypoint_generation.md for detailed generation rules.

  1. Always output valid JSON - No markdown, no extra text
  2. Focus on "How Americans say it" - NOT translation
  3. Every knowledge point must include: Scene context, alternatives, Chinglish trap
  4. 14-day deduplication - No repeated topics or expressions

File Structure

~/.openclaw/state/eng-lang-tutor/  # Default data location
  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
      user_answers.json   # User's answers

Note: Data location can be customized via OPENCLAW_STATE_DIR environment variable.

JSON Schemas

See templates/ directory:

  • state_schema.json
  • keypoint_schema.json
  • quiz_schema.json

Resource References

Prompt Templates (templates/prompts/):

Other Resources:

Examples

See examples/ directory for sample outputs covering all CEFR levels:

LevelKeypointQuiz
A1 (入门级)sample_keypoint_a1.jsonsample_quiz_a1.json
A2 (初级)sample_keypoint_a2.jsonsample_quiz_a2.json
B1 (中级)sample_keypoint_b1.jsonsample_quiz_b1.json
B2 (中高级)sample_keypoint_b2.jsonsample_quiz_b2.json
C1 (高级)sample_keypoint_c1.jsonsample_quiz_c1.json
C2 (精通级)sample_keypoint_c2.jsonsample_quiz_c2.json

User Commands

The bot recognizes these natural language commands:

Initialization

CommandAliasesDescription
startbegin, 开始, 初始化, 你好Start the onboarding process

Learning Content

CommandAliasesDescription
keypoint知识点, 今天, todayView today's knowledge point
keypoint history知识点 历史, 昨天, yesterdayView historical keypoints
quiz测验, test, 测试Take today's quiz (once per day)

Progress & Stats

CommandAliasesDescription
stats进度, 统计, level, XPView learning progress
errors错题本, mistakesView error notebook (recent 5)
errors more错题本 更多Next 5 errors
errors 2026-02错题本 2026-02Filter by month
errors random 5错题本 随机5Random 5 for review
errors stats错题本 统计Show error statistics
errors review错题本 复习, 错题复习Start error review session (5 questions)

Settings

CommandAliasesDescription
config设置, preferencesView current settings
set level B2设置等级 B2Change CEFR level
set style professional设置风格 专业Change tutor style
schedule时间表, 推送时间View/change schedule

Help

CommandAliasesDescription
help帮助, 怎么用Show available commands

Initialization Flow

The 7-step onboarding process:

  1. CEFR Level
  2. Topic Interests
  3. Tutor Style
  4. Oral/Written Ratio
  5. Schedule
  6. Voice Teaching
  7. Confirm

Follow templates/prompts/initialization.md exactly. Display ALL options with numbers (1, 2, 3...).

Step 7 Completion: Set initialized=true + Create cron jobs for keypoint/quiz push times.

State Fields:

  • initialized: Boolean - Whether user completed onboarding
  • onboarding_step: Integer (0-7) - Current step

Response Scenarios

TIMEZONE AWARENESS: All "today" date checks should use state.json schedule.timezone (default: Asia/Shanghai) to ensure consistent behavior across server locations. File paths like daily/2026-02-21/ are timezone-specific.


⛔ MANDATORY BASH COMMANDS - READ THIS FIRST ⛔

When generating content via LLM, you MUST execute bash commands to persist data to disk.

After Keypoint Generation (MANDATORY)

Step 1: LLM generates keypoint JSON
Step 2: ⛔ EXECUTE THIS BASH COMMAND (do NOT skip):
        python3 -m scripts.cli.cli save_daily --content-type keypoint --content '<ESCAPED_JSON>'
        (This auto-generates audio and saves to audio/YYYY-MM-DD/keypoint_full.mp3)
Step 3: ⛔ EXECUTE THIS BASH COMMAND (do NOT skip):
        python3 -m scripts.cli.cli record_view
Step 4: Send audio file via message tool (if audio exists):
        - Read keypoint.json and check if audio.composed field exists
        - If exists, send audio file using message tool with media parameter
        - Audio path: ~/.openclaw/state/eng-lang-tutor/{audio.composed}
Step 5: Display formatted content to user

Audio File Sending (After Keypoint Save)

When keypoint is saved, audio is auto-generated. Send it to user with backward compatibility:

Step 1: Check voice bubble capability

echo $FEISHU_VOICE_BUBBLE_ENABLED

Step 2a: If FEISHU_VOICE_BUBBLE_ENABLED=true (enhanced mode)

Send BOTH voice bubble AND file attachment for best compatibility:

// Voice bubble (handled by enhanced OpenClaw gateway)
{
  "action": "send",
  "media": "~/.openclaw/media/{audio.composed}",
  "asVoice": true
}

// File attachment (fallback for progress bar control)
{
  "action": "send",
  "media": "~/.openclaw/media/{audio.composed}",
  "caption": "🔊 今日知识点语音版"
}

Step 2b: If FEISHU_VOICE_BUBBLE_ENABLED not set or false (standard mode)

Only send file attachment:

{
  "action": "send",
  "media": "~/.openclaw/media/{audio.composed}",
  "caption": "🔊 今日知识点语音版"
}

Audio file info is stored in keypoint.json:

{
  "audio": {
    "composed": "eng-lang-tutor/2026-02-23/keypoint_full.mp3",
    "duration_seconds": 37.7,
    "generated_at": "2026-02-23T02:20:14"
  }
}

IMPORTANT:

  • Audio is saved to ~/.openclaw/media/ (OpenClaw's allowed media directory)
  • Always send audio file BEFORE displaying text content
  • The audio.composed field contains the path relative to ~/.openclaw/media/
  • Enhanced mode (voice bubble) requires OpenClaw gateway patch for Feishu

After Quiz Generation (MANDATORY)

Step 1: LLM generates quiz JSON
Step 2: ⛔ EXECUTE THIS BASH COMMAND (do NOT skip):
        python3 -m scripts.cli.cli save_daily --content-type quiz --content '<ESCAPED_JSON>'
Step 3: Present quiz questions to user

JSON Escaping Rules:

  • Wrap content in single quotes: '{"key": "value"}'
  • Escape internal single quotes: ''\''
  • Example: '{"title": "It'\''s a test"}'

⛔ FAILURE TO EXECUTE BASH COMMANDS = DATA LOSS ⛔


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: Check quiz.json exists (~/.openclaw/state/eng-lang-tutor/daily/YYYY-MM-DD/quiz.json) and quiz.generated == true?
      → YES: Load quiz and present questions
      → NO:
         1. Check if keypoint.json exists for today
            → If NO: Generate keypoint via LLM first
            → ⛔ EXECUTE: python3 -m scripts.cli.cli save_daily --content-type keypoint --content '<ESCAPED_JSON>'
         2. Generate quiz via LLM
         3. Set generated=true in the JSON content
         4. ⛔ EXECUTE: python3 -m scripts.cli.cli save_daily --content-type quiz --content '<ESCAPED_JSON>'
         5. Present questions to user

⛔ CRITICAL: You MUST execute bash commands to save BEFORE presenting to user.

Manual Quiz Before Keypoint Push

User manually requests quiz before scheduled keypoint push time
Bot checks: Does keypoint.json exist for today?
  → NO:
     1. IMMEDIATELY generate keypoint via LLM (do NOT say "will notify later")
     2. ⛔ EXECUTE: python3 -m scripts.cli.cli save_daily --content-type keypoint --content '<ESCAPED_JSON>'
     3. Generate quiz via LLM
     4. ⛔ EXECUTE: python3 -m scripts.cli.cli save_daily --content-type quiz --content '<ESCAPED_JSON>'
     5. Present quiz questions to user
     → All in ONE response - user should receive quiz immediately
  → YES: Proceed with quiz generation normally (see Quiz Already Completed section)

This ensures learning sequence is preserved even for early learners.

⛔ CRITICAL: NEVER tell user "will generate later and notify" - always generate immediately. ⛔ CRITICAL: You MUST execute the bash save commands BEFORE presenting content to user.

Keypoint Query

User: "keypoint" or "知识点" or Cron Push
Bot checks: Does keypoint.json exist for today (~/.openclaw/state/eng-lang-tutor/daily/YYYY-MM-DD/keypoint.json)?
  → NO:
     1. Generate new keypoint via LLM
     2. Set generated=true in the JSON content
     3. ⛔ EXECUTE: python3 -m scripts.cli.cli save_daily --content-type keypoint --content '<ESCAPED_JSON>'
     4. ⛔ EXECUTE: python3 -m scripts.cli.cli record_view
     5. Send audio file via message tool (if audio.composed exists)
     6. Display formatted content to user (REMOVE any [AUDIO:...] tags from text)
  → YES: Check keypoint.generated
      → TRUE: ⛔ EXECUTE: python3 -m scripts.cli.cli record_view, then send audio and display
      → FALSE: Follow steps 1-6 above

⛔ CRITICAL:

  1. You MUST execute bash commands to save BEFORE displaying to user
  2. You MUST remove [AUDIO:...] tags from display text - these are NOT supported and will show as plain text
  3. You SHOULD send audio via message tool if audio.composed field exists

Display Fields (from keypoint.json display object):

FieldDescription
titleMain title with emoji
topic_tagTopic label
formality_tagFormality level
scene_textScene description
expressions_formattedArray of formatted expressions
alternatives_formattedBullet list of alternatives
chinglish_formattedWrong/Correct comparison
examples_formattedArray of dialogue examples
extended_formattedExtended learning content
references_formattedReference links
footerDate and footer info

IMPORTANT:

  • Output assembled Markdown text directly, NOT JSON
  • DO NOT display the audio field in text - it's for message tool media sending only
  • See templates/prompt_templates.md Section 10.3 for full assembly template

Keypoint History

User: "keypoint history" or "知识点 历史"
Bot scans: ~/.openclaw/state/eng-lang-tutor/daily/ directory for YYYY-MM-DD/keypoint.json files
  → NO files found: "📚 No history yet. Start learning with 'keypoint' today!"
  → YES: List keypoints (most recent first), max 10 entries:
      - {date}: {title/topic} (e.g., "2026-02-20: Touch Base - 工作沟通")

Display Format:

📚 **知识点历史记录**

| 日期 | 主题 | 查看 |
|------|------|------|
| 2026-02-20 | Touch Base - 工作沟通 | 输入 `keypoint 2026-02-20` |
| 2026-02-19 | Gonna/Wanna - 口语缩写 | 输入 `keypoint 2026-02-19` |
...

💡 输入 `keypoint 日期` 查看历史知识点详情

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](url)
  • Emojis: Use liberally for visual sections
  • Dividers: ───────────────────

Response Templates

All response templates are documented in templates/prompt_templates.md Section 10:

TemplateSectionDescription
Keypoint Display10.3Daily knowledge point output
Stats Display10.4Learning progress stats
Config Display10.5User settings display
Errors Display10.6Error notebook (paginated)
Error Review10.7Error review session flow
Quiz Result10.8Quiz completion results

Completion Tracking

State Fields

{
  "completion_status": {
    "quiz_completed_date": "2026-02-20",
    "keypoint_view_history": [
      {"date": "2026-02-20", "viewed_at": "2026-02-20T06:45:00"}
    ]
  }
}

Rules

  1. Quiz: Can only take once per day (resets at midnight)
  2. Keypoint: Can view multiple times (including historical pushed keypoints)

Cron Configuration

Default Schedule (UTC+8 / Asia/Shanghai)

TaskDefault TimeDescription
Keypoint Push06:45Daily knowledge point
Quiz Push22:45Daily quiz

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

User-Customizable Schedule

Users can customize their schedule via commands:

set schedule keypoint 7:00
set schedule quiz 21:00

Stored in state.json:

{
  "schedule": {
    "keypoint_time": "07:00",
    "quiz_time": "21:00",
    "timezone": "Asia/Shanghai"
  }
}

---

## Additional Scripts

| Script | Purpose |
|--------|---------|
| cli/command_parser.py | Parse user messages to determine intent |
| scheduling/cron_push.py | Handle scheduled content generation |

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

OpenClaw Skill Growth

Make OpenClaw Skills observable, diagnosable, and safely improvable over time. Use this when the user wants to maintain many SKILL.md files, inspect repeated...

Registry SourceRecently Updated
171Profile unavailable
General

Find Skills for ClawHub

Search for and discover OpenClaw skills from ClawHub (the official skill registry). Activate when user asks about finding skills, installing skills, or wants...

Registry SourceRecently Updated
2871Profile unavailable
General

Skill Listing Polisher

Improve a skill's public listing before publish. Use when tightening title, description, tags, changelog, and scan-friendly packaging so the listing looks cl...

Registry SourceRecently Updated
1130Profile unavailable
General

Skill Priority Setup

Scans installed skills, suggests L0-L3 priority tiers, and auto-configures skill injection policy. Use when: setting up skill priorities, optimizing token bu...

Registry SourceRecently Updated
2510Profile unavailable