Personal AI-powered language tutor. One learner, one chat-first tutor workspace, backed by a Hermes Agent with persistent memory.
The tutor behaves like a real teacher in a text conversation. It remembers who you are, what you struggle with, and what you last practiced.
Browser (Chat + Profile) → SvelteKit app → Hermes Agent → Language Model (OpenRouter)
- SvelteKit frontend — TypeScript, Tailwind, SQLite (Drizzle ORM). Chat UI, onboarding, and Profile page.
- Hermes Agent — Docker container supplying the tutor's identity (
SOUL.md), Skills for learner context and continuity, and the API gateway to the language model. - Tutor Skills — under
hermes/tutor-skills/. Let the tutor inspect the learner profile, study progress, transcripts, and write tutor notes.
- Thin app, rich agent. App owns product state, session boundaries, and UI. Hermes owns tutoring, pedagogical decisions, and memory.
- Chat-first. One tutor workspace. The tutor chooses the next move naturally in conversation.
- Plain text. Assistant messages render as safe Markdown. No visible scoring or raw analytics.
- Durable memory. The tutor writes compact learner facts (level observations, correction preferences, skill gaps) into Hermes durable memory so they survive across sessions.
- Spaced repetition. Phrases and patterns from tutor corrections are captured into review state and resurfaced when due.
- Docker and Docker Compose
- Node.js 22+
- An OpenRouter API key
cp .env.example .env
cp .env frontend/.envEdit .env and paste your OpenRouter API key:
OPENROUTER_API_KEY=sk-or-v1-your-key-here
Leave API_SERVER_KEY as the default — it is used internally between the app
and the Hermes container.
docker compose up -dVerify the Hermes API is reachable:
curl -s http://localhost:8642/v1/models -H "Authorization: Bearer dev-secret-change-me"cd frontend
npm install
npm run devThe dev server starts at http://localhost:5173.
Open http://localhost:5173. The first visit takes you through onboarding.
After that, you enter the tutor chat.
- Chat — the main tutor workspace. Type a message, press Enter to send. Shift+Enter adds a new line.
- Profile — shows what the tutor currently knows about you in durable memory. You can edit the text directly and save changes.
# Ctrl+C in the terminal running npm run dev
docker compose downlangTutor/
├── frontend/ # SvelteKit app
│ ├── src/
│ │ ├── lib/
│ │ │ ├── server/
│ │ │ │ ├── chat.ts # Session lifecycle, Hermes integration
│ │ │ │ ├── hermes/ # Hermes API client
│ │ │ │ ├── db/ # SQLite + Drizzle ORM
│ │ │ │ ├── profile.ts # App-side profile persistence
│ │ │ │ └── env.ts # Environment/config
│ │ │ └── components/ # Shared UI (Markdown, Theme, buttons)
│ │ └── routes/
│ │ ├── app/ # Entry — resumes or creates tutor chat
│ │ ├── chat/[id]/ # Live tutor workspace
│ │ ├── onboarding/ # First-launch setup
│ │ ├── profile/ # Durable tutor memory (user-editable)
│ │ └── api/ # Session lifecycle endpoints
│ ├── drizzle/ # Migration SQL files
│ └── data/ # SQLite database (runtime, gitignored)
├── hermes/
│ ├── config.yaml # Agent configuration
│ ├── SOUL.md # Tutor identity and core behavior
│ ├── memories/ # Durable memory files (runtime)
│ └── tutor-skills/ # Tutor capabilities
│ ├── language-tutor/ # Main tutoring logic + onboarding
│ ├── learner-profile/ # Stable learner identity
│ ├── study-memory/ # Weak items, due review, study ledger
│ ├── session-journal/ # Continuity writes (notes + journal)
│ ├── transcript-history/ # Recent session transcripts
│ ├── language-analytics/ # Word frequency, usage patterns
│ └── shared/scripts/ # learner_data.py (DB access helper)
├── docker-compose.yml # Hermes container
└── .env.example # Environment template
| Variable | Purpose |
|---|---|
OPENROUTER_API_KEY |
Your OpenRouter API key |
API_SERVER_KEY |
Internal auth key (keep default) |
model.default— language model to usemodel.provider— provider (currently openrouter)agent.max_turns— max agent turns per runmemory.memory_enabled— enable Hermes built-in memoryskills.external_dirs— paths to skill directories
| Layer | Technology |
|---|---|
| Frontend | SvelteKit 5 (Svelte 5, TypeScript, Tailwind CSS 4) |
| Database | SQLite via better-sqlite3 + Drizzle ORM |
| Agent | Hermes Agent (Docker) |
| Model | OpenRouter (DeepSeek V4 Flash) |
| Markdown | @humanspeak/svelte-markdown |
| Validation | zod |