"""I18N strings + translation helper for the Streamlit UI. Chrome-level strings only. Sample questions stay in their natural language — the pipeline handles EN + RU both, the toggle only flips the surrounding UI copy. """ # Bilingual UI mixes Cyrillic and Latin in `I18N["ru"]` — silence the # ambiguous-glyph lint at module scope. # ruff: noqa: RUF001 from __future__ import annotations from typing import Any import streamlit as st I18N: dict[str, dict[str, str]] = { "en": { "page_title": "NL → SQL", "tagline": "Natural language in. SQL out. Answer rendered in whichever shape fits the question.", "lang_label": "Language", "lang_en": "EN", "lang_ru": "RU", "metric_kicker": "Chinook business workload", "metric_value": "60 / 60 correct", "metric_percent": "100%", "metric_caption": "30 dev + 30 held-out, balanced split, all ten query categories at 100% on the free-tier codestral pipeline.", "research_kicker": "BIRD Mini-Dev research benchmark", "research_value": "61.5% / 200", "research_short": "Reproducible single-run (codestral, $0). With eval-only hints, the same run scores 62.5%.", "methodology_label": "How the score was reached", "research_caption": ( "This demo runs the reproducible pipeline — 61.5% EA, one free-tier codestral pass, " "no benchmark rescue hints (they are off by default; switching them on takes the same " "run to 62.5%). The project archive also holds eval-only composites — merges of some " "twenty voting runs across other providers with those hints on top. They are not a " "pipeline configuration, do not reproduce, and are not served here. " "Eval hybrid pipeline: " "codestral + " "Sonnet 4.6 bridge + " "grounded-critique retry + " "helallao multi-model voting. " "Scored under " "BIRD-official set semantics. " "The reproducible pipeline is +13.7pp over the GPT-4 zero-shot reference (47.8%) at $0 external cost. The one lever that actually moves it is the generator: the same pipeline scores 68.5% on the free mimo-v2.5 and 79.5% on claude-opus-4-8 at max effort, while six prompt- and context-level techniques from the literature all came out negative. " "On Arcwise-Plat corrected gold the same run scores 60.3% (120/199) — within the benchmark's own annotation corridor, since 33 of 199 questions flip verdict on the choice of gold alone. " "Seven late-stage model rescues on v16→v22, two archive-audit rescores on v23/v24 (qid 1205 via archive sweep, qid 959 via archive-rescore after the day-5 bind-bug fix), and nine targeted P3.F schema-link hints on v25→v31: qid 902 (driverStandings.position vs results.position), qid 1531 (yearmonth.Consumption subquery + SUM(Price/Amount) row-wise), qid 894 (lapTimes.milliseconds first SELECT column), qid 1251 (Patient ⋈ Laboratory ⋈ Examination semi-join), qid 408 (rulings.text filter via cards.uuid join + COUNT(DISTINCT cards.id)), qid 1275 (Laboratory.CENTROMEA/SSB IN ('negative','0') instead of fabricated tokens against Examination), qid 1168 (override projection-discipline: include Patient.Birthday as third SELECT column + ORDER BY Birthday ASC LIMIT 1 on JOIN), qid 1029 (european_football_2 positional inversion: 'highest buildUpPlaySpeed' = lower numeric value, sort ASC + INNER JOIN Team), qid 37 (california_schools 'lowest excellence rate' — BIRD inverts question word-order 'Street, City, Zip and State' to SELECT (Street, City, State, Zip); 'excellence rate' = NumGE1500 / NumTstTakr ASC LIMIT 1 directly on JOIN). Every cell verified via audit_rescore.py — 0 mismatches." ), "settings_header": "Settings", "db_label": "Database", "db_dialect": "Dialect", "db_source": "Source", "schema_explorer_collapsed": "Schema · {n} tables", "schema_explorer_empty": "Schema index empty for this database. Run scripts/build_index.py.", "schema_explorer_caption": "The same chunks the retriever sees — table cards with columns, types, null and distinct stats, sample values, and foreign keys.", "mode_header": "Mode", "mode_accurate": "Accurate", "mode_fast": "Fast", "mode_debug": "Debug", "mode_accurate_caption": "fewshot + verify-retry — best EA", "mode_fast_caption": "no fewshot — fastest, slight EA loss", "mode_debug_caption": "Accurate + raw trace in show-working", "advanced_header": "Advanced retrieval", "schema_top_k": "schema_top_k", "fk_hops": "fk_hops", "table_budget": "table_budget", "sort_schema": "sort schema block (alphabetical)", "sample_size": "extended sample size", "clear_chat": "Clear chat", "ask_placeholder": "Ask a question about this database (EN or RU)…", "ask_intro_label": "Try one of these to start", "diff_simple": "simple", "diff_moderate": "moderate", "diff_challenging": "challenging", "no_samples": "No sample questions curated for this database yet — type your own below.", "spinner_generating": "Generating SQL and executing…", "pipeline_crashed": "Pipeline crashed: {kind}: {msg}", "sql_label": "SQL", "no_sql": "Pipeline produced no SQL.", "wall_model": "{wall:.0f} ms · {model}", "show_working": "Show working — pipeline trace, SQL, metadata", "trace_header": "Pipeline trace", "meta_header": "Metadata", "shape_header": "Result shape", "confidence_label": "Confidence", "repair_attempted": "Repair attempted", "db_field": "Database", "rows_returned": "Rows returned", "columns_field": "Columns", "no_rows": "No result rows.", "rationale_header": "Rationale", "error_kind": "Error", "no_output_warning": "No output format produced.", "conf_high": "High", "conf_med": "Medium", "conf_low": "Low", "conf_unknown": "Unknown", "scalar_label_count": "Count", "scalar_label_sum": "Sum", "scalar_label_average": "Average", "scalar_label_minimum": "Minimum", "scalar_label_maximum": "Maximum", "scalar_label_ratio": "Ratio", "scalar_label_result": "Result", }, "ru": { "page_title": "NL → SQL", "tagline": "На входе — естественный язык. На выходе — SQL и ответ в форме, которая подходит вопросу.", "lang_label": "Язык", "lang_en": "EN", "lang_ru": "RU", "metric_kicker": "Бизнес-нагрузка Chinook", "metric_value": "60 из 60", "metric_percent": "100%", "metric_caption": "30 dev + 30 held-out, сбалансированный сплит, все десять категорий запросов на 100% через бесплатный codestral.", "research_kicker": "Исследовательский бенчмарк BIRD Mini-Dev", "research_value": "61,5% / 200", "research_short": "Воспроизводимый single-run (codestral, $0). С eval-подсказками тот же прогон даёт 62,5%.", "methodology_label": "Как получен результат", "research_caption": ( "Это демо гоняет воспроизводимый пайплайн — 61,5% EA, один прогон на free-tier codestral, " "без benchmark-подсказок (они выключены по умолчанию; с ними тот же прогон даёт 62,5%). " "В архиве проекта есть и eval-only композиции — merge примерно двадцати voting-прогонов " "по другим провайдерам поверх тех же подсказок. Они не являются конфигурацией пайплайна, " "не воспроизводятся и здесь не подаются. " "Eval-гибрид: " "codestral + " "мост к Sonnet 4.6 + " "directed-critique retry + " "multi-model voting через helallao. " "Scoring — " "BIRD-official set-семантика. " "Воспроизводимый пайплайн — +13,7 п.п. над zero-shot GPT-4 (47,8%) при нулевых внешних расходах. Единственный рычаг, который реально его двигает, — генератор: тот же пайплайн даёт 68,5% на бесплатном mimo-v2.5 и 79,5% на claude-opus-4-8 (effort=max), тогда как шесть приёмов уровня промпта и контекста из литературы дали минус. " "На исправленном gold Arcwise-Plat тот же прогон даёт 60,3% (120/199) — внутри собственного коридора разметки бенчмарка: 33 вопроса из 199 меняют вердикт от одного лишь выбора gold. " "Семь late-stage rescue по моделям на пути v16→v22, плюс v23/v24 — archive-sweep и archive-rescore (qid 1205 / qid 959 после day-5 bind-bug fix), плюс v25→v31 — девять узких P3.F schema-link hint'ов: qid 902 (driverStandings.position вместо results.position), qid 1531 (subquery по yearmonth.Consumption + SUM(Price/Amount) построчно), qid 894 (lapTimes.milliseconds первой колонкой), qid 1251 (полу-джойн Patient ⋈ Laboratory ⋈ Examination), qid 408 (фильтр по rulings.text через join cards.uuid + COUNT(DISTINCT cards.id)), qid 1275 (Laboratory.CENTROMEA/SSB IN ('negative','0') вместо несуществующих Examination columns + invented '-'/'+-' tokens), qid 1168 (override projection-discipline: Patient.Birthday как 3-я колонка SELECT + ORDER BY Birthday ASC LIMIT 1 прямо на JOIN), qid 1029 (european_football_2 positional inversion: 'highest buildUpPlaySpeed' = меньшее число, sort ASC + INNER JOIN Team), qid 37 (california_schools 'lowest excellence rate' — BIRD инвертирует word-order вопроса 'Street, City, Zip and State' в SELECT (Street, City, State, Zip); 'excellence rate' = NumGE1500 / NumTstTakr ASC LIMIT 1 прямо на JOIN). Каждая ячейка верифицирована через audit_rescore.py — 0 mismatches." ), "settings_header": "Настройки", "db_label": "База данных", "db_dialect": "Диалект", "db_source": "Источник", "schema_explorer_collapsed": "Схема · {n} таблиц", "schema_explorer_empty": "Индекс схемы пуст для этой БД. Запусти scripts/build_index.py.", "schema_explorer_caption": "Те же чанки, которые видит ретривер — карточки таблиц с колонками, типами, null/distinct, sample-значениями и foreign keys.", "mode_header": "Режим", "mode_accurate": "Точно", "mode_fast": "Быстро", "mode_debug": "Отладка", "mode_accurate_caption": "fewshot + verify-retry — максимальный EA", "mode_fast_caption": "без fewshot — быстрее, EA чуть ниже", "mode_debug_caption": "Точно + сырой trace в show-working", "advanced_header": "Тонкая настройка ретривала", "schema_top_k": "schema_top_k", "fk_hops": "fk_hops", "table_budget": "table_budget", "sort_schema": "сортировать блок схемы (по алфавиту)", "sample_size": "размер расширенного семпла", "clear_chat": "Очистить чат", "ask_placeholder": "Спроси что-нибудь об этой базе (EN или RU)…", "ask_intro_label": "Можно начать с одного из этих вопросов", "diff_simple": "просто", "diff_moderate": "средне", "diff_challenging": "сложно", "no_samples": "Для этой БД пока нет подготовленных вопросов — задай свой ниже.", "spinner_generating": "Генерирую SQL и выполняю…", "pipeline_crashed": "Пайплайн упал: {kind}: {msg}", "sql_label": "SQL", "no_sql": "Пайплайн не выдал SQL.", "wall_model": "{wall:.0f} мс · {model}", "show_working": "Показать работу — trace, SQL, метаданные", "trace_header": "Trace пайплайна", "meta_header": "Метаданные", "shape_header": "Форма результата", "confidence_label": "Уверенность", "repair_attempted": "Был ли repair", "db_field": "База", "rows_returned": "Строк в ответе", "columns_field": "Колонки", "no_rows": "Строки не вернулись.", "rationale_header": "Обоснование", "error_kind": "Ошибка", "no_output_warning": "Формат вывода не был построен.", "conf_high": "Высокая", "conf_med": "Средняя", "conf_low": "Низкая", "conf_unknown": "Неизвестно", "scalar_label_count": "Количество", "scalar_label_sum": "Сумма", "scalar_label_average": "Среднее", "scalar_label_minimum": "Минимум", "scalar_label_maximum": "Максимум", "scalar_label_ratio": "Отношение", "scalar_label_result": "Результат", }, } def t(key: str, **kwargs: Any) -> str: lang = st.session_state.get("lang", "en") template = I18N.get(lang, I18N["en"]).get(key) or I18N["en"].get(key) or key return template.format(**kwargs) if kwargs else template