A Letta Code mod that catches non-English agent output and corrects it immediately.
Built for the GLM model family's notorious language drift: the model suddenly starts replying in Chinese (or another language) mid-conversation, ignores instructions to stay in English, and sometimes doesn't even notice it's doing it. This turns the bug from "unreadable answers" into "a correction lands within seconds."
When any turn ends, the mod checks the agent's output for non-Latin scripts (Chinese, Japanese, Korean, Russian/Cyrillic, Greek, Arabic, Hebrew, Thai, Devanagari, plus CJK punctuation). On detection it injects an immediate corrective turn into the same conversation:
[English Guard] LANGUAGE VIOLATION — your last response was in Chinese, not English.
You are no longer speaking English! You're supposed to be speaking English! Fix yourself.
...
The agent then re-answers in English. The full loop — drift, detection, correction, English re-answer — typically completes in seconds.
Detection is deterministic Unicode script counting, not an LLM call: code blocks, inline code, and URLs are stripped first, then the remaining text is flagged when it contains at least 8 non-Latin characters making up at least 15% of its letters. Quoting a single foreign word won't trigger it; a sentence will.
- Real-time (
turn_endevent) — checks the final assistant message of every turn, plus a throttled history scan that also covers reasoning blocks and text between tool calls. Corrections are delivered through the{ continue }contract, so the corrective turn runs with full tool access in your app. - Polling (every 60s) — scans each agent's recently-active conversations via the local REST API. This catches drift in turns that never pass through your interactive session (scheduled tasks, server-side runs).
Polling runs in one process only (PID lock), so running multiple Letta Code instances won't double-correct.
- Max 3 consecutive corrections per conversation (resets as soon as the agent outputs English)
- Max 10 corrections per conversation per hour
- 30 second cooldown between corrections
npm install -g @coda-rho-bot/english-guard
# or into a project:
npm install @coda-rho-bot/english-guardOr copy mods/english-guard.ts directly into ~/.letta/mods/ if you prefer no package manager.
Run /reload in active sessions (or restart the app) to load it.
/english-guard status: corrections sent, languages caught, thresholds
/english-guard test <text> check any text against the detector (for tuning)
/english-guard on|off enable/disable
/english-guard reload re-read the config file
Optional config at ~/.letta/mods/english-guard.config.json (defaults shown):
{
"enabled": true,
"minNonLatinChars": 8,
"ratioThreshold": 0.15,
"maxConsecutiveCorrections": 3,
"maxCorrectionsPerHour": 10,
"cooldownMs": 30000,
"pollIntervalMs": 60000,
"watchReasoning": true,
"excludedAgents": [],
"excludedConversations": [],
"turnEndEnabled": true,
"pollingEnabled": true
}Runtime state lives in ~/.letta/mods/english-guard.state.json and a rotating debug log in ~/.letta/mods/english-guard-debug.json.
- Local API discovery for the polling/history layers uses
ss(Linux). On other platforms, setLETTA_BASE_URL=http://localhost:<port>in the app's environment and it will be used instead. The real-timeturn_endlayer needs no API access at all. - A response that already rendered cannot be un-sent — the correction supersedes it immediately at turn end. There is no pre-delivery blocking surface in the current mod API.
- The guard watches agent output only (assistant messages and reasoning). User messages and tool results are never scanned or corrected.
This mod is trusted local code and can execute with the user's local permissions. Review the source before installing or modifying it.
MIT