feat: machine translation through a local translator running in the browser's machine
CI / frontend (push) Failing after 17s
CI / backend (push) Successful in 47s

Translator panel in the translation editor and a /translator setup page. The browser talks to
local-translator directly; the server only receives lines marked as machine.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
mrleo1nidandClaude Sonnet 5.5 committed 2026-10-25 18:59:27 +03:00
1 parent a1f5ef8e2d
commit e8d6bf4646
10 files changed
+1039 -4

No files matched your search

+40 -4
View File
@@ -140,8 +140,9 @@ translate russian strings:
* Публикация перевода — **слияние локали** в новую главную версию, а не
подмена главной версии форком.
* Из игр импортируются **все языки** `tl/`.
* Машинный предперевод — **позже, как подключаемый провайдер**. Сейчас
закладывается только состояние строки `machine`.
* Машинный предперевод — **на стороне клиента**: переводит программа
[local-translator](https://gitea.hsrv.site/mrleo1nid/local-translator) на
компьютере переводчика, сервер библиотеки о ней не знает (см. ниже).
* Начинаем с этапа 1.
## Состояние
@@ -192,8 +193,43 @@ translate russian strings:
`…/font`, `…/export`, `…/import`, `DELETE …/{lang}`.
Пока не сделано: UI истории версии (сейчас есть только API), картинки и
озвучка для отдельного языка, правка реплик прямо в плеере, машинный
предперевод (заложено только состояние `machine`).
озвучка для отдельного языка, правка реплик прямо в плеере.
### Машинный перевод через локальный переводчик
Страница `/translator` («Локальный переводчик» в меню профиля) объясняет, как
поставить LM Studio и local-translator, какую модель взять по объёму
видеопамяти, и проверяет связь прямо из браузера. В редакторе перевода кнопка
«Машинный перевод» открывает панель: источник и модель, строк за запрос,
пожелания к стилю (запоминаются для игры), «имена и интерфейс», «обновить
устаревшие».
Как это работает:
* браузер сам ходит на `http://127.0.0.1:8787` (адрес можно сменить на странице
настройки); библиотека получает только обычные `PUT …/i18n/{lang}` с
состоянием `machine`, ни адреса, ни моделей она не видит;
* для каждой игры и пары языков в переводчике создаётся проект
`PGames: <игра> (<исходный> → <язык>)`: контекст из описания игры, глоссарий
из вкладки «Глоссарий», пожелания пользователя. Проект находится по имени и
обновляется перед каждым запуском;
* строки берутся страницами по 40 с фильтром «не переведено» (и «устарело» по
желанию), страница уходит одним заданием, готовое сразу сохраняется. Остановка
отменяет задание в переводчике; повторный запуск продолжает с оставшегося.
Непереведённые из-за ошибки строки (например, модель повредила плейсхолдер)
пропускаются и видны в счётчике ошибок;
* переводчик по умолчанию закрыт для браузера. Адрес сайта вписывается в
`allowed_origins` его `config.toml` (точный адрес, без `*`); для Chrome сервер
отвечает на заголовок Private Network Access, а сам браузер один раз спросит
разрешение на доступ к локальной сети. Страница настройки отличает «не запущен»
от «запущен, но сайт не разрешён»;
* код: `frontend/src/translator/` (`client.ts` — API переводчика, `run.ts` —
цикл перевода, `MachineTranslate.tsx` — панель, `TranslatorSetup.tsx` —
страница настройки); проверки в `frontend/tests/translator-run.test.mjs`.
Ограничения: перевод идёт, пока открыта страница редактора; контекст
(кто говорит, соседние реплики) модели пока не передаётся, только текст строки;
Safari может запрещать https-странице обращаться к локальному http.
Уже сконвертированные версии остаются без ID и без переводов, их нужно
переимпортировать. Пока в библиотеке только тестовые данные, отдельную