Skip to content

Latest commit

 

History

History
254 lines (195 loc) · 9.79 KB

File metadata and controls

254 lines (195 loc) · 9.79 KB

Internationalization (i18n)

CAAL supports multiple languages across all components: voice pipeline (STT, LLM, TTS), web frontend, and mobile app. Language is configured globally — changing it in any client propagates to the voice agent automatically.

Supported Languages

Code Language Frontend Mobile Voice (STT/TTS) Prompts
en English Yes Yes Yes Yes
fr French Yes Yes Yes Yes
it Italian Yes Yes Yes Yes
pt Portuguese (BR) Yes Yes Yes Yes

First-Launch Language Selection

When CAAL starts for the first time, a language selector appears before the setup wizard. This ensures the entire setup experience is in the user's preferred language.

The selector sets a CAAL_LOCALE cookie and saves the language to backend settings. If a user opens CAAL from a new browser after setup, the cookie is automatically synced from backend settings.

Changing the Language

From the Web UI

  1. Open Settings (gear icon)
  2. Under the Agent tab, find the Language dropdown
  3. Select the desired language
  4. The page reloads automatically with the new locale

From the Mobile App

  1. Open Settings
  2. Tap the Language selector
  3. Choose the desired language
  4. The app refreshes immediately

Via API

curl -X POST http://localhost:8889/settings \
  -H "Content-Type: application/json" \
  -d '{"settings": {"language": "fr"}}'

Via settings.json

Edit settings.json at the project root and set the language field:

{
  "language": "fr"
}

The agent reads this on each new session — no restart required.

How It Works

Architecture

settings.json (language: "fr")
    |
    +-- Frontend: CAAL_LOCALE cookie --> next-intl --> French UI
    |
    +-- Mobile: LocaleProvider --> Flutter intl --> French UI
    |
    +-- Voice Agent:
            +-- STT: language="fr" parameter to Whisper
            +-- LLM: French system prompt (prompt/fr/default.md)
            +-- TTS: French voice (Piper siwis-medium)
            +-- Wake greetings: prompt/fr/greetings.txt
            +-- Date/time: French formatting in context

Settings Propagation

  1. User changes language in any client (web, mobile, or API)
  2. Client sends POST /settings with {"settings": {"language": "fr"}}
  3. Backend saves to settings.json
  4. Frontend sets a CAAL_LOCALE cookie and reloads
  5. Mobile updates its LocaleProvider state
  6. The next voice session reads the updated setting at startup

Voice Pipeline

When a voice session starts, the language setting affects:

  • STT: The language parameter is passed to Whisper (Groq or Speaches), improving transcription accuracy for the target language.
  • System Prompt: Loaded from prompt/{language}/default.md. The French prompt includes "Reponds toujours en francais" to ensure the LLM responds in French.
  • TTS Voice: Automatically selects a language-appropriate Piper voice. Kokoro TTS auto-switches to Piper for non-English languages.
  • Wake Greetings: Loaded from prompt/{language}/greetings.txt (one greeting per line). Falls back to English if the language file doesn't exist.
  • Date/Time Context: Injected into the system prompt using localized formatting (e.g., "mercredi 21 janvier 2026", "15 heures 30").

TTS Voice Mapping

Language Piper Voice Description
en piper-en_US-ryan-high Male, US English, high quality
fr piper-fr_FR-siwis-medium Female, French, medium quality
it piper-it_IT-paola-medium Female, Italian, medium quality
pt piper-pt_BR-faber-medium Male, Brazilian Portuguese, medium quality

If Kokoro TTS is configured but the language is not English, the agent automatically switches to Piper with the appropriate voice.

Adding a New Language

To add support for a new language (e.g., German de):

1. Prompt & Greetings Files

Create the prompt directory and files:

prompt/de/
  default.md       # German system prompt (include "Antworte immer auf Deutsch")
  greetings.txt    # One wake greeting per line

Example greetings.txt:

Hallo!
Ja?
Was kann ich für dich tun?
Hey!
Was gibt's?

2. Voice Pipeline (Python)

a) TTS voice mapping — Add a Piper voice in src/caal/settings.py:

PIPER_VOICE_MAP: dict[str, str] = {
    "en": "speaches-ai/piper-en_US-ryan-high",
    "fr": "speaches-ai/piper-fr_FR-siwis-medium",
    "it": "speaches-ai/piper-it_IT-paola-medium",
    "de": "speaches-ai/piper-de_DE-thorsten-high",  # add this
}

b) Date/time formatting — Add formatter functions in src/caal/utils/formatting.py following the pattern of _format_date_french() and _format_time_french(). Then add the language condition in format_date_speech_friendly() and format_time_speech_friendly().

3. Frontend (Next.js)

a) Locale config — Add 'de' to the locales array in frontend/src/i18n/config.ts:

export const locales = ['en', 'fr', 'de'] as const;

b) Message file — Create frontend/messages/de.json using en.json as a template. Translate all values.

c) Language selectors — Add the language to both dropdown arrays:

In frontend/components/settings/settings-panel.tsx:

const LANGUAGES = [
  { code: 'en', label: 'English' },
  { code: 'fr', label: 'Français' },
  { code: 'de', label: 'Deutsch' },  // add this
] as const;

In frontend/components/setup/language-selector.tsx:

const LANGUAGES = [
  { code: 'en', label: 'English' },
  { code: 'fr', label: 'Français' },
  { code: 'de', label: 'Deutsch' },  // add this
] as const;

d) Piper model download — Add the model to the PIPER_MODELS map in language-selector.tsx:

const PIPER_MODELS: Record<string, string> = {
  fr: 'speaches-ai/piper-fr_FR-siwis-medium',
  de: 'speaches-ai/piper-de_DE-thorsten-high',  // add this
};

And in settings-panel.tsx handleLanguageChange:

const piperModels: Record<string, string> = {
  fr: 'speaches-ai/piper-fr_FR-siwis-medium',
  de: 'speaches-ai/piper-de_DE-thorsten-high',  // add this
};

4. Mobile (Flutter)

a) ARB file — Create mobile/lib/l10n/app_de.arb using app_en.arb as a template. Translate all values. Run flutter gen-l10n.

b) Locale provider — Add the locale in mobile/lib/providers/locale_provider.dart:

static const supportedLocales = [Locale('en'), Locale('fr'), Locale('de')];

c) Language option — Add the dropdown entry in mobile/lib/screens/settings_screen.dart.

5. Piper Model

Ensure the Piper TTS model is available. Either pre-install it or let Speaches download it on first use:

curl -X POST http://localhost:8000/v1/models/speaches-ai/piper-de_DE-thorsten-high

Checklist Summary

# What Where
1 System prompt prompt/{lang}/default.md
2 Wake greetings prompt/{lang}/greetings.txt
3 Piper voice mapping src/caal/settings.pyPIPER_VOICE_MAP
4 Date/time formatting src/caal/utils/formatting.py
5 Locale config frontend/src/i18n/config.tslocales
6 UI translations frontend/messages/{lang}.json
7 Settings language list frontend/components/settings/settings-panel.tsxLANGUAGES
8 Setup language list frontend/components/setup/language-selector.tsxLANGUAGES
9 Piper model download maps language-selector.tsx + settings-panel.tsx + setup-wizard.tsxPIPER_MODELS/piperModels
10 Mobile translations mobile/lib/l10n/app_{lang}.arb
11 Mobile locale provider mobile/lib/providers/locale_provider.dart
12 Mobile settings dropdown mobile/lib/screens/settings_screen.dart

File Reference

Component File Purpose
Settings src/caal/settings.py Language storage, prompt/greetings loading, voice map
Voice voice_agent.py Pipeline config
Formatting src/caal/utils/formatting.py Localized date/time
Webhooks src/caal/webhooks.py /settings and /greetings API endpoints
Prompt EN prompt/en/default.md English system prompt
Prompt FR prompt/fr/default.md French system prompt
Prompt IT prompt/it/default.md Italian system prompt
Greetings EN prompt/en/greetings.txt English wake greetings
Greetings FR prompt/fr/greetings.txt French wake greetings
Greetings IT prompt/it/greetings.txt Italian wake greetings
Prompt PT prompt/pt/default.md Portuguese (BR) system prompt
Greetings PT prompt/pt/greetings.txt Portuguese (BR) wake greetings
Frontend config frontend/src/i18n/config.ts Locale list
Frontend request frontend/src/i18n/request.ts Cookie-based locale detection
Frontend EN frontend/messages/en.json English UI translations
Frontend FR frontend/messages/fr.json French UI translations
Frontend IT frontend/messages/it.json Italian UI translations
Frontend PT frontend/messages/pt.json Portuguese (BR) UI translations
Language selector frontend/components/setup/language-selector.tsx Pre-wizard language choice
Settings panel frontend/components/settings/settings-panel.tsx In-app language switching
Mobile provider mobile/lib/providers/locale_provider.dart Locale state management
Mobile EN mobile/lib/l10n/app_en.arb English mobile translations
Mobile FR mobile/lib/l10n/app_fr.arb French mobile translations
Mobile IT mobile/lib/l10n/app_it.arb Italian mobile translations
Mobile PT mobile/lib/l10n/app_pt.arb Portuguese (BR) mobile translations