55 lines
3.3 KiB
Markdown
55 lines
3.3 KiB
Markdown
# Language support
|
|||
|
|
|
||
|
|
LearnHarness supports English and Russian. Settings → General contains independent
|
||
|
|
interface and speech recognition language selectors. The microphone also has a
|
||
|
|
speech language selector. Each offers System default, English, and Русский.
|
||
|
|
|
||
|
|
System default uses the preferred browser language (the operating system's
|
||
|
|
preferred language in the desktop app); Russian locales select Russian and other
|
||
|
|
locales select English. Explicit choices persist in `settings.json` as
|
||
|
|
`general.language` and `general.sttLanguage`. Removing a field restores automatic
|
||
|
|
selection. Changing one preference preserves the other general settings.
|
||
|
|
|
||
|
|
The interface changes immediately, including accessibility labels and the desktop
|
||
|
|
menu. New AI teaching, questions, plans, practice, graph descriptions, research,
|
||
|
|
figures, and demos use the interface language. Existing conversations and imported
|
||
|
|
source material retain their authored text. A session retains the language of its
|
||
|
|
latest foreground turn so automatic follow-ups can use the same language after a
|
||
|
|
restart; an explicit app language preference takes precedence.
|
||
|
|
|
||
|
|
Speech recognition uses Deepgram Nova-3 with an explicit `language=en` or
|
||
|
|
`language=ru`. A recording captures the selected language when it starts and keeps
|
||
|
|
that language through reconnections. The selector is disabled while recording;
|
||
|
|
changes elsewhere take effect on the next recording. Audio capture, deferred
|
||
|
|
transcript insertion, stopping, and cancellation retain their existing behavior.
|
||
|
|
|
||
|
|
## Maintaining translations
|
||
|
|
|
||
|
|
The pure localization functions live in `src/core/i18n.ts` and are exported through
|
||
|
|
the core barrel. English and Russian catalogs are in `src/core/locales/en.json` and
|
||
|
|
`ru.json`. English source phrases are message keys. Add every new app-owned message
|
||
|
|
to both catalogs, use named interpolation parameters, and use plural entries with
|
||
|
|
`Intl.PluralRules` for counts. Russian entries may use `one`, `few`, `many`, and
|
||
|
|
`other` forms. Keep code, provider/model names, identifiers, and user-authored text
|
||
|
|
out of translation lookups.
|
||
|
|
|
||
|
|
React components use `useI18n()` from `components/i18n.tsx`. The root provider gets
|
||
|
|
server-resolved initial settings and locale to preserve hydration. General-setting
|
||
|
|
writes share a serialized read-modify-write path; other surfaces use the existing
|
||
|
|
settings-saved signal. Server and agent code receive an explicit language rather
|
||
|
|
than depending on a mutable global translation state.
|
||
|
|
|
||
|
|
Some existing protocol errors arrive preformatted in English. Localization can
|
||
|
|
recognize cataloged application templates at the display boundary, preserving the
|
||
|
|
canonical error values used for classification and any third-party diagnostics.
|
||
|
|
Raw technical instructions, code, and user overrides remain editable source data.
|
||
|
|
|
||
|
|
The desktop shell has its own small catalog in `electron/language.cjs`, packaged
|
||
|
|
with the shell. Its narrow `lh:language` channel accepts only `en` and `ru` from a
|
||
|
|
trusted application window. Russian prose uses Noto Sans because Source Sans 3
|
||
|
|
has no Cyrillic subset. Explicit font choices continue to take precedence.
|
||
|
|
|
||
|
|
`tests/i18n.test.tsx` covers preference validation, automatic selection, independent
|
||
|
|
STT requests, catalog parity and interpolation, Russian plural forms, SSR locale
|
||
|
|
isolation, translated dialogs and exports, agent instructions, and native labels.
|