← Back to Plugins
Tools

Plugin German Tutor

jsiic08 By jsiic08 👁 27 views ▲ 0 votes

German tutoring agent plugin for OpenClaw โ€” CEFR-calibrated, scenario-based lessons with graduated corrections (Sprechi)

GitHub

Configuration Example

"plugins": {
  "entries": {
    "german-tutor": {
      "enabled": true,
      "config": {
        "agentId": "sprechi",
        "activeProfile": "jae"
      }
    }
  }
}

README

# Sprechi โ€” German Tutoring Agent for OpenClaw

An OpenClaw agent that conducts one-on-one German conversation lessons on
Discord. Sprechi speaks Hochdeutsch only, calibrates to the learner's CEFR
level, runs task-based scenarios, and corrects errors with graduated
reproduction prompts โ€” all grounded in second language acquisition research.

## What this directory contains

```
german-tutor/
โ”œโ”€โ”€ README.md                 โ† you are here
โ”œโ”€โ”€ package.json              โ† npm package manifest
โ”œโ”€โ”€ openclaw.plugin.json      โ† OpenClaw plugin registration + config schema
โ”œโ”€โ”€ index.ts                  โ† plugin entry point (registers the hook)
โ”œโ”€โ”€ src/                      โ† plugin source code
โ”‚   โ”œโ”€โ”€ config.ts             โ† config parser
โ”‚   โ”œโ”€โ”€ profile.ts            โ† learner profile loader
โ”‚   โ”œโ”€โ”€ scenarios.ts          โ† scenario loader
โ”‚   โ”œโ”€โ”€ levels.ts             โ† CEFR level doc loader
โ”‚   โ””โ”€โ”€ prompt-inject.ts      โ† builds the context block
โ””โ”€โ”€ content/                  โ† all teaching content (edit these, not the code)
    โ”œโ”€โ”€ persona.md            โ† the 11 pedagogical principles
    โ”œโ”€โ”€ levels/               โ† CEFR reference docs
    โ”‚   โ”œโ”€โ”€ A1.md
    โ”‚   โ”œโ”€โ”€ A2.md
    โ”‚   โ””โ”€โ”€ B1.md
    โ”œโ”€โ”€ profiles/             โ† learner profiles (one per student)
    โ”‚   โ””โ”€โ”€ jae.json
    โ””โ”€โ”€ scenarios/            โ† 13 task-based scenarios
        โ”œโ”€โ”€ biergarten.json
        โ”œโ”€โ”€ bahnhof.json
        โ””โ”€โ”€ ... (11 more)
```

## How it works

Sprechi is both a configured **agent** in OpenClaw and a **plugin** that
supplements that agent with German tutoring context. The two pieces work
together:

### The agent
- Defined in `openclaw.json` under `agents.list` as `sprechi`
- Has its own workspace at `~/.openclaw/workspace-sprechi/`
- The workspace contains `SOUL.md` โ€” Sprechi's core identity and
  teaching philosophy that OpenClaw loads into the system prompt automatically
- Bound to one specific Discord channel via an entry in `bindings` โ€” any
  message in that channel routes to `sprechi` instead of the default agent
- Threads inside that channel inherit the binding automatically

### The plugin
- Registered in `openclaw.json` under `plugins.entries.german-tutor`
- On every turn in Sprechi's channel, the plugin's `before_prompt_build`
  hook fires and injects a context block in front of the system prompt
- The context block contains:
  1. The full 11 pedagogical principles from `content/persona.md`
  2. The CEFR reference document matching the learner's level (A1, A2, or B1)
  3. A learner-context block summarizing the learner's profile
  4. The current scenario (role, information gap, vocabulary, success criteria)
  5. A correction-watch list of the learner's top recurring errors, each
     tagged with priority and a specific action directive

The plugin guards on `ctx.agentId === "sprechi"` so it only activates for
this agent. Other OpenClaw agents are unaffected.

### Per-turn flow

```
User sends Discord message in bound channel
       โ”‚
       โ–ผ
OpenClaw routes to sprechi agent
       โ”‚
       โ–ผ
before_prompt_build hook fires
       โ”‚
       โ–ผ
Plugin loads profile + level doc + scenario + persona
       โ”‚
       โ–ผ
Plugin builds context block (~2500 tokens)
       โ”‚
       โ–ผ
Context block prepended to system prompt
       โ”‚
       โ–ผ
Agent call made with full context (persona + CEFR + profile + scenario)
       โ”‚
       โ–ผ
Response posted to Discord
       โ”‚
       โ–ผ
chatlog plugin logs the exchange to markdown
```

## Configuration

### Where things live

| What | Path |
|------|------|
| Main OpenClaw config | `~/.openclaw/openclaw.json` |
| Agent workspace (SOUL.md) | `~/.openclaw/workspace-sprechi/` |
| Plugin code + content | `~/openclaw/extensions/german-tutor/` |
| Extension logs | `~/.openclaw/logs/` and `/tmp/openclaw/openclaw-*.log` |
| Chatlog output | `~/.openclaw/chatlog/` (see chatlog plugin) |

### Plugin config in openclaw.json

```json
"plugins": {
  "entries": {
    "german-tutor": {
      "enabled": true,
      "config": {
        "agentId": "sprechi",
        "activeProfile": "jae"
      }
    }
  }
}
```

- `agentId`: which agent the plugin activates for. Defaults to `sprechi`.
- `activeProfile`: which profile file to load from `content/profiles/`.
  Defaults to `jae`. Set to `partner` to load `content/profiles/partner.json`.

### Agent registration

```json
"agents": {
  "list": [
    {
      "id": "sprechi",
      "name": "Sprechi",
      "workspace": "/home/agentshik/.openclaw/workspace-sprechi"
    }
  ]
}
```

### Channel binding

```json
"bindings": [
  {
    "agentId": "sprechi",
    "match": {
      "channel": "discord",
      "peer": { "kind": "channel", "id": "1494366718292660224" }
    }
  }
]
```

Replace the channel ID to bind Sprechi to a different Discord channel.

---

## Common tasks

### Change the learner's current scenario

Edit the profile file and change `current_scenario` to any scenario ID
from `content/scenarios/`:

```bash
nano ~/openclaw/extensions/german-tutor/content/profiles/jae.json
```

```json
{
  "current_scenario": "therapie",  โ† change this
  ...
}
```

Available scenario IDs: `biergarten`, `bahnhof`, `wohnung`, `arzt`,
`wegbeschreibung`, `cafe`, `reklamation`, `verabredung`, `party`,
`beschwerde`, `storepruefung`, `kita`, `therapie`.

**No restart needed** โ€” the plugin reads the profile on every turn.

### Change the learner's CEFR level

Edit the profile file:

```json
{
  "cefr_level": "B1",  โ† change to A1, A2, or B1
  "cefr_by_skill": {
    "speaking": "B1",
    "listening": "B1",
    "reading": "B1",
    "writing": "A2"
  },
  ...
}
```

The plugin will automatically load `content/levels/B1.md` instead of A2.

### Update recurring errors

After a tutoring session, update `recurring_errors` in the profile so
Sprechi knows what to watch for:

```json
"recurring_errors": [
  {
    "pattern": "Drops articles before nouns in casual speech",
    "priority": "critical",
    "principle": "P4",
    "action": "correct EVERY time"
  },
  {
    "pattern": "Your new pattern here",
    "priority": "high",       โ† critical | high | medium | low
    "principle": "P5",        โ† which principle applies
    "action": "explicit correction + reproduction"
  }
]
```

Priority order: `critical` > `high` > `medium` > `low`. Keep the list
short โ€” 3-5 items max. Too many and Sprechi will over-correct.

### Add a new scenario

Create a new JSON file in `content/scenarios/` following the schema:

```json
{
  "id": "my_scenario",
  "title": "Der deutsche Titel",
  "description": "Short English description of the situation",
  "learner_role": "Description in German of who the learner is",
  "agent_role": "Description in German of who Sprechi plays",
  "information_gap": "What the learner doesn't know that Sprechi does โ€” this is what drives the scenario forward",
  "pre_task_vocab": [
    "der Artikel (article)",
    "das Wort (word)"
  ],
  "success_criteria": [
    "Learner does X",
    "Learner correctly uses Y"
  ],
  "grammar_opportunities": [
    "Pattern: Ich mรถchte einen...",
    "Structure: weil-clause"
  ]
}
```

**Rules for scenarios**:
- `pre_task_vocab` items must include the article for all nouns โ€” this
  reinforces P4 from the data layer
- 8-12 vocabulary items is the sweet spot
- 4-6 success criteria
- 2-4 grammar opportunities
- The `information_gap` is what makes it a *task-based* scenario, not
  just free chat โ€” there needs to be something the learner has to
  discover or figure out

Once the file exists, set `current_scenario` in the profile to match
the new `id`.

### Add a new learner profile (for a second user)

1. Copy `content/profiles/jae.json` to `content/profiles/partner.json`
2. Edit the new file โ€” change `user_id`, `display_name`, `cefr_level`,
   `recurring_errors`, `interests`, etc.
3. Either:
   - Change the plugin's `activeProfile` config to `"partner"` to switch
     entirely, OR
   - (Future: Block 3) Bind the partner's own Discord channel to a second
     agent that uses the partner profile

### Edit Sprechi's teaching persona

Two files control Sprechi's persona:

**`~/.openclaw/workspace-sprechi/SOUL.md`** โ€” core identity and teaching
philosophy. Loaded by OpenClaw automatically into the system prompt.
Keep this focused on *who Sprechi is*.

**`content/persona.md`** โ€” the 11 detailed pedagogical principles
(P1-P11). Injected by the plugin every turn. Keep this focused on
*how Sprechi teaches*.

The distinction is roughly:
- SOUL.md = identity, warmth, Discord formatting rules, session structure
- persona.md = the full teaching methodology with numbered principles

If you want Sprechi to behave differently (e.g. more or less strict
about corrections, different session pacing), edit `content/persona.md`.

### Edit CEFR level constraints

`content/levels/A1.md`, `A2.md`, and `B1.md` define what grammar and
vocabulary Sprechi may use at each level. Each doc has four sections:

- **Grammar you may use**: tenses, clause types, cases, verb types
- **Grammar you must avoid in your own output**: explicit no-go list
- **Vocabulary**: word family count, introduction rate
- **Sentence complexity**: max length, clause rules
- **Correction focus at this level**: what to prioritize catching

If Sprechi is using structures that are too complex or too simple,
edit the corresponding level file.

---

## Monitoring & debugging

### Check if the gateway is running

```bash
systemctl --user status openclaw-gateway.service
```

### Watch the logs

```bash
journalctl --user -u openclaw-gateway.service -f
```

### See config health

```bash
cat ~/.openclaw/logs/config-health.json | python3 -m json.tool
```

### See the full per-turn log

```bash
tail -100 /tmp/openclaw/openclaw-$(date +%Y-%m-%d).log
```

### When to restart the gateway

You need to restart after:
- Editing `openclaw.json` (agent, bindings, or plugin config changes)
- Editing any plugin source code (`.ts` files)
- Adding or removing plugin files

You do **NOT** need to restart after:
- Editing profile JSON files
- Ed

... (truncated)
tools

Comments

Sign in to leave a comment

Loading comments...