Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

49 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LocalTeacher

A local-first CLI for practicing conversational English with an AI tutor. Everything runs on your machine — your voice, your transcripts, and your conversations never leave it.

Type or talk, and the tutor answers in text and speech.

🇪🇸 Versión en español más abajo


Table of contents


How it works

LocalTeacher chains four local tools together. Nothing is sent to a remote API: the only network traffic is downloading the tools and models on first run.

Text conversation:

your text -> tutor prompt -> Ollama -> reply printed -> Piper -> ffplay -> your speakers

Voice conversation:

mic -> FFmpeg (16 kHz mono WAV) -> whisper.cpp -> transcript
                                                      |
                                                      v
                       tutor prompt -> Ollama -> reply printed -> Piper -> ffplay

The tutor layer is deliberately text-in / text-out. Audio input becomes text before the tutor is called, and speech synthesis happens after the reply is printed — so if playback fails you still get your answer, just with a warning.

On startup, the app walks a chain of checks and fixes anything that is missing, asking before it installs:

  1. Config and state files
  2. User config (native language, level, correction style, correction mode)
  3. Ollama installed → service running → a valid local model selected
  4. FFmpeg installed → a working microphone input discovered and saved
  5. whisper.cpp built → Whisper model downloaded
  6. Piper installed → voice model downloaded

whisper.cpp, Piper, and their models are pinned to specific versions and verified against hardcoded SHA-256 checksums before use. Temporary recording-*.wav files are cleaned up at startup, on exit, and on Ctrl+C / SIGTERM.


Tech stack

Layer Technology Role
App Go 1.26 (stdlib CLI, no framework) Session loop, wizards, orchestration
LLM Ollama Local tutor replies over http://localhost:11434/api/chat
Speech-to-text whisper.cpp v1.9.1 whisper-cli transcribes WAV → text
Text-to-speech Piper 2023.11.14-2 Tutor reply → WAV (en_US-lessac-medium)
Audio I/O FFmpeg / ffplay Mic discovery, recording, playback
System info gopsutil/v4 CPU, RAM, disk, OS, best-effort GPU detection
Concurrency golang.org/x/sync/errgroup Parallel system probing
CI GitHub Actions gofmt, go vet, govulncheck, tests on Linux/macOS/Windows

The model picker suggests: llama3.2:3b (default), qwen2.5:3b, qwen2.5:7b, and llama3.1:8b.


Requirements

You need to have installed:

  • Go 1.26+
  • FFmpeg (includes ffplay) — microphone recording and audio playback
  • curl, tar, and cmake — used to build whisper.cpp on first run
  • A working microphone and speakers

Installed for you on first run (with your confirmation):

  • Ollama — via the official install script (Linux), brew (macOS), or winget (Windows)
  • whisper.cpp — downloaded and compiled locally
  • Piper — prebuilt release for your platform
  • Models — Whisper ggml-base.en (~148 MB) and the Piper voice (~63 MB)

Disk budget: roughly 2–5 GB depending on the Ollama model you pick, plus ~250 MB for the speech models and the whisper.cpp build.


Installation

git clone https://github.com/FaceNach/LocalTeacher.git
cd LocalTeacher
go build -o localteacher ./cmd
./localteacher

Or run it straight from source:

go run ./cmd

The first run is the slow one: it may build whisper.cpp and download models. After that, startup is just a series of quick checks.


Usage

Start the app and you'll get a prompt.

  • Type a message → the tutor replies in text and reads it aloud.
  • Press Enter on an empty line (or type r) → start recording. Press Enter again to stop; your speech is transcribed and answered.

Commands:

Command What it does
r or empty Enter Start / stop voice recording
/help Show the available commands
/config Review and change your settings without restarting
exit, /exit Quit LocalTeacher

Ctrl+C also exits cleanly and removes temporary audio files.


Configuration

Set on first run and editable any time with /config:

Setting Options
Native language English, Spanish, Portuguese, French, Italian, German
Level Beginner, Intermediate, Advanced
Correction style Gentle, Balanced, Immersive, Detailed, Strict
Correction mode Important, All, None
Ollama model Any model available locally
Audio input Detected microphone backend and device

Changes made through /config are validated, saved, and applied to the live session — the tutor prompt, the Ollama client, and the recorder are rebuilt in place, so no restart is needed. (Settings can't be changed while a recording is in progress.)

The tutor's behavior comes from a system prompt templated with these values: keep the conversation natural, adapt to the user's level, correct kindly and briefly, and always end with one follow-up question.


Where your data lives

What Location
User config <user config dir>/localteacher/userconfig.json
System state <user config dir>/localteacher/system_state.json
whisper.cpp + model <user config dir>/localteacher/whisper/
Piper + voice <user config dir>/localteacher/piper/
Temporary WAVs <user cache dir>/localteacher/temp/

<user config dir> is ~/.config on Linux, ~/Library/Application Support on macOS, and %AppData% on Windows.


Project structure

cmd/
  main.go                  # entry point: cleanup, signal handling, app.Build().Run()
internal/
  app/                     # CLI session: wiring, command table, input loop
  startup/                 # first-run setup and prerequisite checks
    setup/
      config/              # user config read/validate/atomic save
      options/             # languages, levels, correction styles, model options
      wizard/              # interactive wizards + the /config menu
  service/                 # TeacherService: coordinates tutor, Ollama, audio
  tutor/                   # system prompt generation and tutor rules
  ollama/                  # install checks, service, model listing/pull, chat client
  audio/                   # high-level audio facade
    ffmpeg/                # mic discovery, WAV recording, ffplay playback
    input/                 # recorder start/stop state for the selected mic
    whisper/               # whisper.cpp install, model download, transcription
    piper/                 # Piper install, voice download, synthesis
  platform/                # CPU, RAM, disk, OS, arch and GPU detection
  fsutil/                  # paths, disk space, SHA-256 verification
  cleaning/                # temporary WAV cleanup
  defaultsConst/           # names, URLs, checksums, timeouts
  ui/                      # terminal output (with control-character sanitizing)

Design notes:

  • External tools are wrapped behind small interfaces (audioRecorder, audioTranscriber, speechSynthesizer, audioPlayer, llmClient), so the session and service layers are testable with fakes.
  • Every external command runs through exec.CommandContext with explicit arguments and timeouts.
  • Model replies and transcripts are stripped of terminal control characters before printing, so a model can't inject ANSI escape sequences into your terminal.

Development

go test ./...      # unit tests
gofmt -l .         # formatting check
go vet ./...       # vet

Tests use fakes rather than real FFmpeg, whisper.cpp, Ollama, microphones, or network access, and redirect config/cache locations with environment variables and t.TempDir(). CI runs formatting, vet, govulncheck, and the full test suite on Linux, macOS, and Windows for every push to main and every pull request.

See AGENTS.md for the working notes and conventions used while building this.


Status and roadmap

This is a learning project, built incrementally, with unit tests across most packages.

Working today: text chat, voice-to-voice conversation, spoken replies, in-app settings menu, cross-platform setup wizards, checksum-verified installs.

Not implemented yet:

  • Conversation memory / session history beyond the current turn
  • Streaming Ollama responses

License

MIT — see LICENSE.




LocalTeacher (Español)

Una CLI local-first para practicar conversación en inglés con un tutor de IA. Todo corre en tu máquina: tu voz, tus transcripciones y tus conversaciones nunca salen de ahí.

Escribí o hablá, y el tutor te responde por texto y en voz.


Índice


Cómo funciona

LocalTeacher encadena cuatro herramientas locales. No se envía nada a ninguna API remota: el único tráfico de red es la descarga de las herramientas y los modelos en la primera ejecución.

Conversación por texto:

tu texto -> prompt del tutor -> Ollama -> respuesta impresa -> Piper -> ffplay -> tus parlantes

Conversación por voz:

micrófono -> FFmpeg (WAV mono 16 kHz) -> whisper.cpp -> transcripción
                                                             |
                                                             v
                    prompt del tutor -> Ollama -> respuesta impresa -> Piper -> ffplay

La capa del tutor es a propósito texto-entra / texto-sale. El audio se convierte en texto antes de llamar al tutor, y la síntesis de voz ocurre después de imprimir la respuesta: si falla la reproducción igual ves tu respuesta, solo que con una advertencia.

Al iniciar, la app recorre una cadena de verificaciones y arregla lo que falte, preguntando antes de instalar:

  1. Archivos de configuración y estado
  2. Config de usuario (idioma nativo, nivel, estilo y modo de corrección)
  3. Ollama instalado → servicio corriendo → modelo local válido seleccionado
  4. FFmpeg instalado → micrófono funcional detectado y guardado
  5. whisper.cpp compilado → modelo de Whisper descargado
  6. Piper instalado → modelo de voz descargado

whisper.cpp, Piper y sus modelos están fijados a versiones específicas y se verifican contra checksums SHA-256 hardcodeados antes de usarse. Los WAV temporales (recording-*.wav) se limpian al iniciar, al salir y con Ctrl+C / SIGTERM.


Tecnologías

Capa Tecnología Rol
App Go 1.26 (CLI con stdlib, sin framework) Loop de sesión, wizards, orquestación
LLM Ollama Respuestas del tutor vía http://localhost:11434/api/chat
Voz a texto whisper.cpp v1.9.1 whisper-cli transcribe WAV → texto
Texto a voz Piper 2023.11.14-2 Respuesta del tutor → WAV (en_US-lessac-medium)
Audio I/O FFmpeg / ffplay Detección de micrófono, grabación, reproducción
Info del sistema gopsutil/v4 CPU, RAM, disco, SO y detección de GPU (best-effort)
Concurrencia golang.org/x/sync/errgroup Sondeo del sistema en paralelo
CI GitHub Actions gofmt, go vet, govulncheck y tests en Linux/macOS/Windows

El selector de modelos sugiere: llama3.2:3b (por defecto), qwen2.5:3b, qwen2.5:7b y llama3.1:8b.


Requisitos

Tenés que tener instalado:

  • Go 1.26+
  • FFmpeg (incluye ffplay) — grabación de micrófono y reproducción de audio
  • curl, tar y cmake — se usan para compilar whisper.cpp en la primera ejecución
  • Un micrófono y parlantes funcionando

Se instalan solos en la primera ejecución (con tu confirmación):

  • Ollama — con el script oficial (Linux), brew (macOS) o winget (Windows)
  • whisper.cpp — se descarga y compila localmente
  • Piper — release precompilada para tu plataforma
  • Modelos — Whisper ggml-base.en (~148 MB) y la voz de Piper (~63 MB)

Espacio en disco: entre 2 y 5 GB según el modelo de Ollama que elijas, más unos 250 MB para los modelos de voz y la compilación de whisper.cpp.


Instalación

git clone https://github.com/FaceNach/LocalTeacher.git
cd LocalTeacher
go build -o localteacher ./cmd
./localteacher

O directamente desde el código fuente:

go run ./cmd

La primera ejecución es la lenta: puede compilar whisper.cpp y descargar modelos. Después de eso, el arranque es solo una serie de chequeos rápidos.


Uso

Arrancá la app y vas a ver el prompt.

  • Escribí un mensaje → el tutor responde por texto y lo lee en voz alta.
  • Enter en una línea vacía (o escribí r) → empieza a grabar. Enter otra vez para parar: tu voz se transcribe y se responde.

Comandos:

Comando Qué hace
r o Enter vacío Inicia / detiene la grabación de voz
/help Muestra los comandos disponibles
/config Revisa y cambia tus ajustes sin reiniciar
exit, /exit Sale de LocalTeacher

Ctrl+C también sale limpio y borra los archivos de audio temporales.


Configuración

Se define en la primera ejecución y se puede editar en cualquier momento con /config:

Ajuste Opciones
Idioma nativo Inglés, Español, Portugués, Francés, Italiano, Alemán
Nivel Principiante, Intermedio, Avanzado
Estilo de corrección Gentle, Balanced, Immersive, Detailed, Strict
Modo de corrección Important, All, None
Modelo de Ollama Cualquier modelo disponible localmente
Entrada de audio Backend y dispositivo de micrófono detectados

Los cambios hechos con /config se validan, se guardan y se aplican a la sesión en curso: el prompt del tutor, el cliente de Ollama y el grabador se reconstruyen en el momento, así que no hace falta reiniciar. (No se pueden cambiar los ajustes mientras hay una grabación activa.)

El comportamiento del tutor sale de un system prompt armado con estos valores: mantener la conversación natural, adaptarse al nivel del usuario, corregir con amabilidad y brevedad, y terminar siempre con una pregunta de seguimiento.


Dónde se guardan tus datos

Qué Ubicación
Config de usuario <dir de config>/localteacher/userconfig.json
Estado del sistema <dir de config>/localteacher/system_state.json
whisper.cpp + modelo <dir de config>/localteacher/whisper/
Piper + voz <dir de config>/localteacher/piper/
WAV temporales <dir de caché>/localteacher/temp/

<dir de config> es ~/.config en Linux, ~/Library/Application Support en macOS y %AppData% en Windows.


Estructura del proyecto

cmd/
  main.go                  # punto de entrada: limpieza, señales, app.Build().Run()
internal/
  app/                     # sesión CLI: wiring, tabla de comandos, loop de entrada
  startup/                 # setup inicial y verificación de prerequisitos
    setup/
      config/              # lectura, validación y guardado atómico de la config
      options/             # idiomas, niveles, estilos de corrección, modelos
      wizard/              # wizards interactivos + menú de /config
  service/                 # TeacherService: coordina tutor, Ollama y audio
  tutor/                   # generación del system prompt y reglas del tutor
  ollama/                  # instalación, servicio, modelos y cliente de chat
  audio/                   # fachada de audio de alto nivel
    ffmpeg/                # detección de micrófono, grabación WAV, playback ffplay
    input/                 # estado start/stop del grabador para el micrófono elegido
    whisper/               # instalación de whisper.cpp, modelo y transcripción
    piper/                 # instalación de Piper, voz y síntesis
  platform/                # detección de CPU, RAM, disco, SO, arquitectura y GPU
  fsutil/                  # rutas, espacio en disco, verificación SHA-256
  cleaning/                # limpieza de WAV temporales
  defaultsConst/           # nombres, URLs, checksums y timeouts
  ui/                      # salida por terminal (sanitizando caracteres de control)

Notas de diseño:

  • Las herramientas externas están envueltas detrás de interfaces chicas (audioRecorder, audioTranscriber, speechSynthesizer, audioPlayer, llmClient), así las capas de sesión y servicio se pueden testear con fakes.
  • Todo comando externo corre con exec.CommandContext, con argumentos explícitos y timeouts.
  • A las respuestas del modelo y a las transcripciones se les quitan los caracteres de control antes de imprimirlas, para que un modelo no pueda inyectar secuencias ANSI en tu terminal.

Desarrollo

go test ./...      # tests unitarios
gofmt -l .         # chequeo de formato
go vet ./...       # vet

Los tests usan fakes en lugar de FFmpeg, whisper.cpp, Ollama, micrófonos o red reales, y redirigen las rutas de config/caché con variables de entorno y t.TempDir(). La CI corre formato, vet, govulncheck y toda la suite de tests en Linux, macOS y Windows en cada push a main y en cada pull request.

En AGENTS.md están las notas de trabajo y las convenciones usadas para construir esto.


Estado y próximos pasos

Este es un proyecto de aprendizaje, construido de forma incremental, con tests unitarios en la mayoría de los paquetes.

Ya funciona: chat por texto, conversación voz a voz, respuestas habladas, menú de ajustes dentro de la app, wizards de setup multiplataforma e instalaciones verificadas por checksum.

Todavía no está implementado:

  • Memoria de conversación / historial de sesión más allá del turno actual
  • Respuestas de Ollama en streaming

Licencia

MIT — ver LICENSE.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages