recognition: глобальный переключатель языка вывода [general].language
- новое поле [general].language (ru|en, дефолт en) — единый источник языка локализованного title детектора и локали запросов к метабазам; original_title всегда на языке оригинала - локаль TMDB (поиск + credits) выводится из него, [metadata.tmdb].language убран - промпт LLM явно задаёт язык title с fallback на оригинал
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-07-24
|
||||
@@ -0,0 +1,107 @@
|
||||
## Context
|
||||
|
||||
Язык локализованных полей вывода (`title`, режиссёр) сейчас задаётся неявно и в
|
||||
двух местах: промпт LLM говорит модели вернуть «каноническое название» без
|
||||
указания языка (модель решает сама), а клиент TMDB жёстко берёт локаль из
|
||||
`[metadata.tmdb].language` с дефолтом `ru-RU`. Это два несогласованных рычага
|
||||
для одного решения. Требуется один явный переключатель, единый для детектора и
|
||||
метабаз.
|
||||
|
||||
Затрагиваемые пакеты: `internal/config` (новое поле), `internal/recognize`
|
||||
(промпт), `internal/metadata` (TMDB-клиент), проброс из `cmd/jellybit` в
|
||||
recognizer и TMDB. Конвенция конфига — `docs/conventions/config.md`
|
||||
(самодокументируемый `config.example.toml`, валидация на старте).
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Одно top-level поле `language` (`ru`|`en`, дефолт `en`) — единственный
|
||||
источник языка локализованного вывода.
|
||||
- `title` от LLM и локаль TMDB (поиск + credits) следуют этому полю.
|
||||
- `original_title` не затрагивается ни при каком значении.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- Гарантированная локализация имён режиссёров (провайдеры их почти не
|
||||
переводят — best-effort).
|
||||
- Языки помимо `ru`/`en`, автоопределение языка по контенту, per-раздача
|
||||
override.
|
||||
- Локаль TVDB/TVMaze: TVDB extended не параметризуем языком в текущем клиенте,
|
||||
TVMaze — англоязычный; вне охвата этого изменения (охват — LLM и TMDB).
|
||||
|
||||
## Decisions
|
||||
|
||||
**1. Место конфига — `[general].language`, значения `ru`|`en`, дефолт `en`.**
|
||||
Поле кросс-каттинг (и recognition, и metadata-match) и по классу — это
|
||||
presentation-настройка отображения, ровно как уже живущий в `[general]`
|
||||
`timezone` («таймзона отображения времени»). Селим рядом с ним — единый дом
|
||||
таких настроек, не плодим второй паттерн места. Значения — короткие языковые
|
||||
коды, а не локали (`ru-RU`): локаль — диалект конкретного провайдера, его
|
||||
выводит сам провайдер (см. решение 2). Значение хранится голой строкой, как
|
||||
остальные enum-подобные поля конфига (`llm.type`, `log.format`) — проект
|
||||
осознанно не типизирует их. Валидация: значение вне `ru`/`en` → ошибка старта
|
||||
(fail-fast, **по образцу `llm.type`**, а не permissive `log.level`), форма
|
||||
сообщения — `unsupported language %q (supported: ru, en)`. Нормализацию «пусто →
|
||||
`en`» держим НЕ в `validate()` (он чист — только собирает ошибки), а в аксессоре
|
||||
`Config` по образцу `DisplayLocation()`; `Default()` при этом сеет `"en"`.
|
||||
Альтернативы отклонены: `[recognition].language` назвала бы поле по одному из
|
||||
двух потребителей; top-level рядом с `timezone` не согласуется с уже сложившимся
|
||||
домом presentation-настроек.
|
||||
|
||||
**2. `[metadata.tmdb].language` удаляется; локаль выводит провайдер.** В общий
|
||||
слой (config/cmd) едет абстрактный `ru`/`en`; диалект TMDB `ru-RU`/`en-US`
|
||||
выводит сам `internal/metadata/tmdb.go` — тотальным `switch` с default-веткой
|
||||
`en-US` (defense in depth: невозможный вход не роняет запрос без локали). Так
|
||||
знание диалекта принадлежит тому, кто на нём говорит: второй локализуемый
|
||||
провайдер (TVDB с иным синтаксисом локали) добавит свой маппинг у себя, а не
|
||||
расширит общий слой. Остаточный `tmdbDefaultLanguage = "ru-RU"` и его fallback в
|
||||
`NewTMDB` **удаляются** — это скрытый второй дефолт, противоречащий заявленному
|
||||
`en-US`. Второго способа задать язык не остаётся (нет рассинхрона). Ломающее
|
||||
изменение конфига переворачивает дефолт локали TMDB `ru-RU`→`en-US`; фиксируем в
|
||||
proposal и миграции. Альтернатива «оставить `[metadata.tmdb].language` как
|
||||
override» отклонена: две ручки для одного решения противоречат «второго способа
|
||||
быть не должно».
|
||||
|
||||
**3. Директива языка в промпте — только для `title`, с fallback на оригинал.**
|
||||
Добавляем в промпт распознавания явную строку: вернуть `title` на языке
|
||||
`language`, при отсутствии перевода — на языке оригинала (не выдумывать).
|
||||
Семантически совпадает с поведением TMDB `language` (локализованное поле с
|
||||
fallback на оригинал), поэтому обе стороны согласованы. Язык прокидывается в
|
||||
`buildMessages`/`systemPrompt` из конфига через `Recognizer`.
|
||||
|
||||
**4. Режиссёр — та же локаль в запрос credits, best-effort.** Клиент TMDB уже
|
||||
передаёт `language` в поиск; тем же значением параметризуем запрос credits
|
||||
(`Director`). Имена людей TMDB локализует не всегда — где перевода нет, приходит
|
||||
оригинал; это не ошибка и не проваливает выборку (best-effort уже закреплён
|
||||
спекой metadata-match).
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [Имена режиссёров редко локализованы у провайдеров] → best-effort по спеке:
|
||||
при отсутствии перевода — оригинал; ожидание зафиксировано в proposal, отказа
|
||||
не вызывает.
|
||||
- [Ломающее изменение конфига: удаление `[metadata.tmdb].language` + флип
|
||||
дефолта на `en-US`] → go-toml молча игнорирует неизвестный ключ, поэтому
|
||||
деплой с оставленным `[metadata.tmdb].language = "ru-RU"` тихо переключится на
|
||||
английский. Решение: НЕ вводим отклонение неизвестных ключей (лишняя машинерия
|
||||
ради единственного деплоя), а прописываем обязательный ручной шаг в миграции
|
||||
ниже. Существующие «русские» деплои выставляют `[general].language = "ru"` и
|
||||
убирают старый ключ.
|
||||
- [Дефолт `en` переименует имена папок медиатеки на английский] → косметика:
|
||||
Jellyfin идентифицирует контент по id-тегу метабазы (TVDB/IMDb в имени папки),
|
||||
а не по языку названия, поэтому распознавание не ломается. `original_title`
|
||||
(ось поиска в базах) от `language` не зависит. Осознанный дефолт.
|
||||
- [LLM может проигнорировать языковую директиву на слабой модели] → директива
|
||||
best-effort, как и весь недоверенный вывод LLM; безопасность по-прежнему на
|
||||
валидации и гейте матча, не на языке `title`.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Выкатка бинаря с новым полем; дефолт `en` активен сразу.
|
||||
2. Деплой, где ожидались русские названия, добавляет `[general].language = "ru"`
|
||||
в конфиг и удаляет `[metadata.tmdb].language` (обязательный ручной шаг —
|
||||
валидатор про удалённый ключ не предупреждает).
|
||||
3. Откат — вернуть прежний бинарь; `language` в конфиге игнорируется старой
|
||||
версией (unknown-поле go-toml не роняет парсинг), `[metadata.tmdb].language`
|
||||
при откате нужно вернуть, если он был.
|
||||
@@ -0,0 +1,59 @@
|
||||
## Why
|
||||
|
||||
Приложение и медиатека — на русском, но распознавание и метабазы часто отдают
|
||||
`title` и режиссёра на английском (или, наоборот, на русском там, где хочется
|
||||
латиницу). Сейчас язык локализованного названия задан неявно и вразнобой: LLM
|
||||
сам решает, на каком языке вернуть `title`, а TMDB жёстко умолчанием `ru-RU`.
|
||||
Нужен один явный переключатель языка вывода, единый для детектора и метабаз, с
|
||||
предсказуемым дефолтом.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Вводится единый конфиг `[general].language` со значениями `ru`|`en`, **по
|
||||
умолчанию `en`** (рядом с `[general].timezone` — тот же класс
|
||||
presentation-настройки отображения). Он задаёт язык *локализованных* полей
|
||||
вывода — `title` и режиссёра. `original_title` он не затрагивает: оно всегда
|
||||
остаётся на языке оригинала картины.
|
||||
- **recognition**: промпт LLM явно требует возвращать `title` на выбранном
|
||||
языке (локализованное название с fallback на оригинал, если перевода нет).
|
||||
Контракт `original_title` не меняется.
|
||||
- **metadata-match**: локаль запросов к TMDB (`language`) выводится из
|
||||
глобального `language` (`ru`→`ru-RU`, `en`→`en-US`), а не задаётся отдельно.
|
||||
В запрос credits (режиссёр) тоже передаётся эта локаль — best-effort: имена
|
||||
людей провайдеры локализуют не всегда, где перевода нет, остаётся оригинал.
|
||||
- **BREAKING (конфиг)**: поле `[metadata.tmdb].language` удаляется — теперь это
|
||||
единственный способ задать язык, второго не остаётся. Дефолт локали TMDB
|
||||
меняется с `ru-RU` на `en-US` (следствие общего дефолта `en`).
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
(нет — новых доменов не вводим)
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `recognition`: требование к промпту LLM — `title` возвращается на языке,
|
||||
заданном глобальным `language` (fallback на оригинал при отсутствии
|
||||
перевода); контракт `original_title` не меняется.
|
||||
- `metadata-match`: локаль запроса к TMDB выводится из глобального `language`
|
||||
(вместо отдельного `[metadata.tmdb].language`), та же локаль передаётся в
|
||||
запрос режиссёра (best-effort).
|
||||
|
||||
## Impact
|
||||
|
||||
- **Конфиг**: новое поле `[general].language` (валидация `ru`|`en`, дефолт
|
||||
`en`); удаление `[metadata.tmdb].language`; обновление `config.example.toml`
|
||||
и `docs/conventions/config.md`.
|
||||
- **Медиатека на диске**: имя папки Jellyfin строится из локализованного
|
||||
`title` (`recognize.go` подменяет `plan.Title` каноническим именем матча),
|
||||
поэтому дефолт `en` даёт английские имена папок. Это косметика: Jellyfin
|
||||
идентифицирует контент по id-тегу метабазы (TVDB/IMDb в имени папки), а не по
|
||||
языку названия, поэтому распознавание медиатеки не ломается.
|
||||
- **Код**: `internal/config` (парсинг/валидация/дефолт нового поля, удаление
|
||||
старого), `internal/recognize/prompt.go` (язык `title` в промпте),
|
||||
`internal/metadata/tmdb.go` (локаль из глобального, передача в credits),
|
||||
проброс `language` из конфига в recognizer и клиента TMDB.
|
||||
- **Поведение**: дефолтный язык `title`/режиссёра меняется на английский;
|
||||
существующие деплои, полагавшиеся на `ru-RU`, должны выставить
|
||||
`language = "ru"`.
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Локаль запроса к TMDB
|
||||
|
||||
Локаль запросов к TMDB SHALL выводиться из глобальной настройки `language`
|
||||
(`ru`|`en`, дефолт `en`): `ru` → `ru-RU`, `en` → `en-US`. Отдельной настройки
|
||||
локали у TMDB быть SHALL NOT — глобальный `language` единственный источник.
|
||||
|
||||
Эту локаль система SHALL передавать параметром `language` как в запрос поиска,
|
||||
так и в запрос credits (режиссёр). На стороне поиска локаль влияет ТОЛЬКО на
|
||||
локализованное поле `Title`/`Name`; поле `original_title`/`original_name`
|
||||
остаётся на языке оригинала, поэтому оригинальная сторона сравнения не
|
||||
затрагивается. На стороне credits передача локали — best-effort: имена людей
|
||||
провайдер локализует не всегда, при отсутствии перевода имя остаётся на языке
|
||||
оригинала, и это не проваливает выборку режиссёра.
|
||||
|
||||
#### Scenario: Локаль по умолчанию — английская
|
||||
|
||||
- **GIVEN** TMDB включён, глобальный `language` не задан в конфиге
|
||||
- **WHEN** выполняется поиск фильма
|
||||
- **THEN** запрос содержит `language=en-US`
|
||||
- **AND** в кандидате `Title` приходит на английском, а `OriginalTitle` — на языке оригинала
|
||||
|
||||
#### Scenario: language=ru даёт русскую локаль
|
||||
|
||||
- **GIVEN** TMDB включён, глобальный `language` = `ru`
|
||||
- **WHEN** выполняется поиск фильма с русской локализацией
|
||||
- **THEN** запрос содержит `language=ru-RU`
|
||||
- **AND** в кандидате `Title` приходит на русском, а `OriginalTitle` — на языке оригинала
|
||||
|
||||
#### Scenario: Локаль передаётся и в запрос режиссёра
|
||||
|
||||
- **GIVEN** подтверждённый матч TMDB и глобальный `language` = `ru`
|
||||
- **WHEN** выполняется запрос credits за режиссёром
|
||||
- **THEN** запрос содержит `language=ru-RU`
|
||||
- **AND** при отсутствии локализованного имени режиссёр остаётся на языке оригинала, выборка не проваливается
|
||||
@@ -0,0 +1,54 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Контракт LLM на оригинальное и локализованное названия
|
||||
|
||||
Промпт распознавания SHALL требовать от модели всегда заполнять и `title`, и
|
||||
`original_title`. Если отдельного оригинального названия нет или контент
|
||||
российского происхождения, модель SHALL дублировать `title` в
|
||||
`original_title`. При неуверенности в оригинальном названии модель SHALL
|
||||
дублировать `title`, а не выдумывать название (защита от ложного авто-матча).
|
||||
|
||||
Промпт SHALL явно задавать язык локализованного `title` из глобальной
|
||||
настройки `language` (`ru`|`en`, дефолт `en`): модель SHALL возвращать `title`
|
||||
на выбранном языке, а при отсутствии перевода — на языке оригинала (fallback).
|
||||
Языковая директива SHALL касаться ТОЛЬКО `title`; `original_title` остаётся на
|
||||
языке оригинала независимо от `language` (правила дублирования выше не
|
||||
меняются). `provider_hint` и структурные поля (`files[].src`, роли, нумерация)
|
||||
языковой директивой не затрагиваются.
|
||||
|
||||
Разбор ответа SHALL оставаться устойчивым к пустому `original_title`: пустое
|
||||
значение не отбраковывается и не вызывает correction-ретрай; сверка
|
||||
gracefully использует доступные названия.
|
||||
|
||||
#### Scenario: Российский фильм — дублирование
|
||||
|
||||
- **GIVEN** раздача российского фильма без отдельного оригинального названия
|
||||
- **WHEN** модель возвращает план
|
||||
- **THEN** `title` и `original_title` заполнены одинаковым каноническим названием
|
||||
|
||||
#### Scenario: Пустой original_title не ломает разбор
|
||||
|
||||
- **GIVEN** ответ модели с пустым `original_title`
|
||||
- **WHEN** план разбирается
|
||||
- **THEN** разбор успешен без correction-ретрая
|
||||
- **AND** сверка использует `title` (и `provider_hint`)
|
||||
|
||||
#### Scenario: title приходит на языке из настройки
|
||||
|
||||
- **GIVEN** `language` = `en` и иностранный фильм с известным английским названием
|
||||
- **WHEN** модель возвращает план
|
||||
- **THEN** промпт требовал `title` на английском
|
||||
- **AND** `original_title` остаётся на языке оригинала (директива его не касается)
|
||||
|
||||
#### Scenario: Промпт задаёт fallback на оригинал при отсутствии перевода
|
||||
|
||||
- **GIVEN** `language` = `en`
|
||||
- **WHEN** собирается промпт распознавания
|
||||
- **THEN** промпт требует при отсутствии перевода вернуть `title` на языке
|
||||
оригинала, а не выдумывать название
|
||||
|
||||
#### Scenario: Дефолтный язык — английский
|
||||
|
||||
- **GIVEN** `language` не задан в конфиге
|
||||
- **WHEN** собирается промпт распознавания
|
||||
- **THEN** промпт требует `title` на английском (дефолт `en`)
|
||||
@@ -0,0 +1,28 @@
|
||||
## 1. Конфиг
|
||||
|
||||
- [x] 1.1 Добавить поле `Language string` в `[general]`-секцию `internal/config` (рядом с `Timezone`), парсинг из TOML
|
||||
- [x] 1.2 `Default()` сеет `Language = "en"`; `validate()` остаётся чистым (не мутирует Config), только отвергает значение вне {`ru`,`en`} по образцу `llm.type` — сообщение `unsupported language %q (supported: ru, en)`
|
||||
- [x] 1.3 Нормализацию «пусто → `en`» и выдачу абстрактного кода вынести в аксессор `Config` по образцу `DisplayLocation()` (не в `validate()`)
|
||||
- [x] 1.4 Удалить поле `Language` из `MetadataProvider`/TMDB-секции и его дефолт `ru-RU` в `Default()`
|
||||
- [x] 1.5 Обновить `config.example.toml`: добавить `[general].language` с комментарием, убрать `[metadata.tmdb].language`
|
||||
- [x] 1.6 Обновить `docs/conventions/config.md`, если там упомянута локаль TMDB
|
||||
- [x] 1.7 Тесты config: дефолт `en` (пустой конфиг → `en`); приём `ru`/`en`; **отказ старта на значении вне ru/en** (напр. `de` → ошибка конфига)
|
||||
|
||||
## 2. Локаль TMDB из глобального языка
|
||||
|
||||
- [x] 2.1 `TMDBConfig` принимает абстрактный `ru`/`en`; диалект `ru`→`ru-RU`, `en`→`en-US` выводит сам `tmdb.go` тотальным `switch` с default-веткой `en-US`
|
||||
- [x] 2.2 Удалить остаточный `tmdbDefaultLanguage = "ru-RU"` и его fallback в `NewTMDB` (скрытый второй дефолт); поправить комментарии, ссылающиеся на дефолт `ru-RU`
|
||||
- [x] 2.3 Прокинуть абстрактный `language` из конфига в конструктор TMDB-клиента (`cmd/jellybit/serve.go`)
|
||||
- [x] 2.4 Передавать выведенную локаль в запрос credits (`Director`), не только в поиск
|
||||
- [x] 2.5 Тесты TMDB: `en`→`en-US` и `ru`→`ru-RU` в параметрах `Search` и `Director`; пустой/непокрытый вход → `en-US` (default-ветка)
|
||||
|
||||
## 3. Язык title в промпте LLM
|
||||
|
||||
- [x] 3.1 Прокинуть абстрактный `language` из конфига в `Recognizer` (поле `recognize.Config`, дефолт в `New`) и в сборку промпта (`systemPrompt` const → builder-функция с параметром языка)
|
||||
- [x] 3.2 Директива в промпте: `title` на выбранном языке, при отсутствии перевода — оригинал (не выдумывать); `original_title` не трогать
|
||||
- [x] 3.3 Тесты: промпт содержит корректную языковую директиву при `en` и при `ru`; при незаданном языке — английскую (дефолт)
|
||||
|
||||
## 4. Верификация
|
||||
|
||||
- [x] 4.1 `task gate` зелёный (build/vet/lint/test/race/покрытие/секреты)
|
||||
- [x] 4.2 `openspec validate content-language-switch --strict` проходит
|
||||
@@ -101,19 +101,39 @@ plan-санитайзинге.
|
||||
|
||||
### Requirement: Локаль запроса к TMDB
|
||||
|
||||
Запрос поиска к TMDB SHALL передавать параметр `language`, по умолчанию
|
||||
`ru-RU`, со значением, настраиваемым конфигом `[metadata.tmdb].language`.
|
||||
Это влияет только на локализованное поле `Title`/`Name`; поле
|
||||
`original_title`/`original_name` остаётся на языке оригинала, поэтому
|
||||
оригинальная сторона сравнения не затрагивается.
|
||||
Локаль запросов к TMDB SHALL выводиться из глобальной настройки `language`
|
||||
(`ru`|`en`, дефолт `en`): `ru` → `ru-RU`, `en` → `en-US`. Отдельной настройки
|
||||
локали у TMDB быть SHALL NOT — глобальный `language` единственный источник.
|
||||
|
||||
#### Scenario: Локализованный заголовок приходит по-русски
|
||||
Эту локаль система SHALL передавать параметром `language` как в запрос поиска,
|
||||
так и в запрос credits (режиссёр). На стороне поиска локаль влияет ТОЛЬКО на
|
||||
локализованное поле `Title`/`Name`; поле `original_title`/`original_name`
|
||||
остаётся на языке оригинала, поэтому оригинальная сторона сравнения не
|
||||
затрагивается. На стороне credits передача локали — best-effort: имена людей
|
||||
провайдер локализует не всегда, при отсутствии перевода имя остаётся на языке
|
||||
оригинала, и это не проваливает выборку режиссёра.
|
||||
|
||||
- **GIVEN** TMDB включён, `language` не задан в конфиге
|
||||
#### Scenario: Локаль по умолчанию — английская
|
||||
|
||||
- **GIVEN** TMDB включён, глобальный `language` не задан в конфиге
|
||||
- **WHEN** выполняется поиск фильма
|
||||
- **THEN** запрос содержит `language=en-US`
|
||||
- **AND** в кандидате `Title` приходит на английском, а `OriginalTitle` — на языке оригинала
|
||||
|
||||
#### Scenario: language=ru даёт русскую локаль
|
||||
|
||||
- **GIVEN** TMDB включён, глобальный `language` = `ru`
|
||||
- **WHEN** выполняется поиск фильма с русской локализацией
|
||||
- **THEN** запрос содержит `language=ru-RU`
|
||||
- **AND** в кандидате `Title` приходит на русском, а `OriginalTitle` — на языке оригинала
|
||||
|
||||
#### Scenario: Локаль передаётся и в запрос режиссёра
|
||||
|
||||
- **GIVEN** подтверждённый матч TMDB и глобальный `language` = `ru`
|
||||
- **WHEN** выполняется запрос credits за режиссёром
|
||||
- **THEN** запрос содержит `language=ru-RU`
|
||||
- **AND** при отсутствии локализованного имени режиссёр остаётся на языке оригинала, выборка не проваливается
|
||||
|
||||
### Requirement: Нормализация названий при сравнении
|
||||
|
||||
Нормализация названий для гейта сильного матча SHALL сводить букву `ё` к `е`,
|
||||
|
||||
@@ -16,6 +16,14 @@
|
||||
`original_title`. При неуверенности в оригинальном названии модель SHALL
|
||||
дублировать `title`, а не выдумывать название (защита от ложного авто-матча).
|
||||
|
||||
Промпт SHALL явно задавать язык локализованного `title` из глобальной
|
||||
настройки `language` (`ru`|`en`, дефолт `en`): модель SHALL возвращать `title`
|
||||
на выбранном языке, а при отсутствии перевода — на языке оригинала (fallback).
|
||||
Языковая директива SHALL касаться ТОЛЬКО `title`; `original_title` остаётся на
|
||||
языке оригинала независимо от `language` (правила дублирования выше не
|
||||
меняются). `provider_hint` и структурные поля (`files[].src`, роли, нумерация)
|
||||
языковой директивой не затрагиваются.
|
||||
|
||||
Разбор ответа SHALL оставаться устойчивым к пустому `original_title`: пустое
|
||||
значение не отбраковывается и не вызывает correction-ретрай; сверка
|
||||
gracefully использует доступные названия.
|
||||
@@ -33,6 +41,26 @@ gracefully использует доступные названия.
|
||||
- **THEN** разбор успешен без correction-ретрая
|
||||
- **AND** сверка использует `title` (и `provider_hint`)
|
||||
|
||||
#### Scenario: title приходит на языке из настройки
|
||||
|
||||
- **GIVEN** `language` = `en` и иностранный фильм с известным английским названием
|
||||
- **WHEN** модель возвращает план
|
||||
- **THEN** промпт требовал `title` на английском
|
||||
- **AND** `original_title` остаётся на языке оригинала (директива его не касается)
|
||||
|
||||
#### Scenario: Промпт задаёт fallback на оригинал при отсутствии перевода
|
||||
|
||||
- **GIVEN** `language` = `en`
|
||||
- **WHEN** собирается промпт распознавания
|
||||
- **THEN** промпт требует при отсутствии перевода вернуть `title` на языке
|
||||
оригинала, а не выдумывать название
|
||||
|
||||
#### Scenario: Дефолтный язык — английский
|
||||
|
||||
- **GIVEN** `language` не задан в конфиге
|
||||
- **WHEN** собирается промпт распознавания
|
||||
- **THEN** промпт требует `title` на английском (дефолт `en`)
|
||||
|
||||
### Requirement: Пред-парс имени релиза
|
||||
|
||||
Перед вызовом LLM система SHALL выполнять дешёвый пред-парс имени торрента
|
||||
|
||||
Reference in New Issue
Block a user