diff --git a/api/routes.py b/api/routes.py index f46b314..3f101f1 100644 --- a/api/routes.py +++ b/api/routes.py @@ -283,6 +283,15 @@ _LOGIN_LOCALE = { "invalid_pw": "Ung\u00fcltiges Passwort", "conn_failed": "Verbindung fehlgeschlagen", }, + "ru": { + "lang": "ru-RU", + "title": "\u0412\u043e\u0439\u0442\u0438", + "subtitle": "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u044c, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c", + "placeholder": "\u041f\u0430\u0440\u043e\u043b\u044c", + "btn": "\u0412\u043e\u0439\u0442\u0438", + "invalid_pw": "\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043f\u0430\u0440\u043e\u043b\u044c", + "conn_failed": "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f", + }, "zh": { "lang": "zh-CN", "title": "\u767b\u5f55", diff --git a/static/i18n.js b/static/i18n.js index a6bb51c..f1e2bc6 100644 --- a/static/i18n.js +++ b/static/i18n.js @@ -450,6 +450,11 @@ const LOCALES = { profile_use: 'Use', profile_switch_title: 'Switch to this profile', profile_delete_title: 'Delete this profile', + profile_default_label: '(default)', + profile_name_placeholder: 'Profile name (lowercase, a-z 0-9 hyphens)', + profile_clone_label: 'Clone config from active profile', + profile_base_url_placeholder: 'Base URL (optional, e.g. http://localhost:11434)', + profile_api_key_placeholder: 'API key (optional)', manage_profiles: 'Manage profiles', profiles_load_failed: 'Failed to load profiles', profiles_busy_switch: 'Cannot switch profiles while agent is running', @@ -473,6 +478,465 @@ const LOCALES = { bg_error_multi: (count) => `${count} sessions have encountered an error`, }, + ru: { + _lang: 'ru', + _label: 'Русский', + _speech: 'ru-RU', + cancelling: 'Отменяю…', + cancel_failed: 'Не удалось отменить: ', + mic_denied: 'Доступ к микрофону запрещён. Проверьте разрешения браузера.', + mic_no_speech: 'Речь не распознана. Попробуйте ещё раз.', + mic_network: 'Распознавание речи недоступно.', + mic_error: 'Ошибка ввода речи: ', + session_imported: 'Сеанс импортирован', + import_failed: 'Не удалось импортировать: ', + import_invalid_json: 'Неверный JSON', + image_pasted: 'Изображение вставлено: ', + edit_message: 'Редактировать сообщение', + regenerate: 'Сгенерировать ответ заново', + copy: 'Копировать', + copied: 'Скопировано!', + you: 'Вы', + thinking: 'Думаю', + expand_all: 'Развернуть всё', + collapse_all: 'Свернуть всё', + edit_failed: 'Не удалось отредактировать: ', + regen_failed: 'Не удалось сгенерировать заново: ', + reconnect_active: 'Ответ всё ещё генерируется. Обновить, когда будет готово?', + reconnect_finished: 'Когда вы уходили, ответ ещё генерировался. Сообщения могли обновиться.', + approval_heading: 'Требуется подтверждение', + approval_desc_prefix: 'Обнаружена опасная команда', + approval_btn_once: 'Разрешить один раз', + approval_btn_once_title: 'Разрешить только эту команду (Enter)', + approval_btn_session: 'Разрешить на этот сеанс', + approval_btn_session_title: 'Разрешить для этого сеанса разговора', + approval_btn_always: 'Всегда разрешать', + approval_btn_always_title: 'Всегда разрешать команды по этому шаблону', + approval_btn_deny: 'Запретить', + approval_btn_deny_title: 'Запретить — не выполнять эту команду', + approval_responding: 'Отвечаю…', + untitled: 'Без названия', + n_messages: (n) => `${n} сообщений`, + model_unavailable: ' (недоступна)', + model_unavailable_title: 'Эта модель больше не входит в ваш текущий список провайдеров', + provider_mismatch_warning: (m, p) => + `"${m}" может не работать с вашим настроенным провайдером (${p}). Всё равно отправить или запустите \`hermes model\` в терминале, чтобы переключиться.`, + provider_mismatch_label: 'Несовпадение провайдера', + model_custom_label: 'Пользовательский ID модели', + model_custom_placeholder: 'например, openai/gpt-5.4', + cmd_help: 'Показать доступные команды', + cmd_clear: 'Очистить сообщения беседы', + cmd_compact: 'Сжать контекст беседы', + cmd_model: 'Переключить модель (например, /model gpt-4o)', + cmd_workspace: 'Переключить рабочее пространство по названию', + cmd_new: 'Начать новую сессию чата', + cmd_usage: 'Показать или скрыть использование токенов', + cmd_theme: 'Переключить тему (dark/light/slate/solarized/monokai/nord/oled)', + cmd_personality: 'Переключить личность агента', + cmd_skills: 'Показать доступные навыки Hermes', + available_commands: 'Доступные команды:', + type_slash: 'Введите /, чтобы увидеть команды', + conversation_cleared: 'Беседа очищена', + model_usage: 'Использование: /model ', + no_model_match: 'Нет модели, соответствующей "', + switched_to: 'Переключено на ', + workspace_usage: 'Использование: /workspace ', + no_workspace_match: 'Нет рабочего пространства, соответствующего "', + switched_workspace: 'Переключено на рабочее пространство: ', + workspace_switch_failed: 'Не удалось переключить рабочее пространство: ', + new_session: 'Новая сессия создана', + compressing: 'Запрашиваю сжатие контекста...', + token_usage_on: 'Отображение токенов включено', + token_usage_off: 'Отображение токенов выключено', + theme_usage: 'Использование: /theme ', + theme_set: 'Тема: ', + no_active_session: 'Нет активной сессии', + + no_personalities: 'Личности не найдены (добавьте их в ~/.hermes/personalities/)', + clarify_heading: 'Требуется уточнение', + clarify_hint: 'Выберите вариант или введите свой ответ ниже.', + clarify_input_placeholder: 'Введите ответ…', + clarify_other: 'Другое', + clarify_responding: 'Отвечаю…', + clarify_send: 'Отправить', + cmd_compact_alias: 'Устаревший псевдоним для /compress', + cmd_compress: 'Сжать контекст беседы (использование: /compress [тема])', + command_label: 'Команда', + compress_complete_label: 'Сжатие завершено', + compress_failed_label: 'Ошибка сжатия', + compress_running_label: 'Сжатие…', + context_compaction_label: 'Сжатие контекста', + focus_label: 'Фокус', + model_search_no_results: 'Модели не найдены', + model_search_placeholder: 'Поиск моделей…', + reference_only_label: 'Только справка', + settings_label_skin: 'Скин', + workspace_empty_dir: 'Это рабочее пространство пусто.', + workspace_empty_no_path: 'Рабочее пространство не выбрано. Настройте его в Настройки → Рабочее пространство.', + available_personalities: 'Доступные личности:', + personality_switch_hint: '\n\nИспользуйте `/personality ` для переключения или `/personality none` для сброса.', + personalities_load_failed: 'Не удалось загрузить личности', + personality_cleared: 'Личность очищена', + personality_set: 'Личность: ', + failed_colon: 'Не удалось: ', + no_workspace: 'Нет рабочего пространства', + dialog_confirm_title: 'Подтвердить действие', + dialog_prompt_title: 'Введите значение', + dialog_confirm_btn: 'Подтвердить', + unsaved_confirm: 'У вас есть несохранённые изменения в предпросмотре. Отменить и перейти дальше?', + discard: 'Отменить', + save: 'Сохранить', + edit: 'Редактировать', + clear: 'Очистить', + create: 'Создать', + remove: 'Удалить', + save_title: 'Сохранить изменения', + edit_title: 'Редактировать этот файл', + saved: 'Сохранено', + save_failed: 'Не удалось сохранить: ', + image_load_failed: 'Не удалось загрузить изображение', + file_open_failed: 'Не удалось открыть файл', + downloading: (name) => `Скачиваю ${name}…`, + double_click_rename: 'Дважды щёлкните, чтобы переименовать', + renamed_to: 'Переименовано в ', + rename_failed: 'Не удалось переименовать: ', + delete_title: 'Удалить', + delete_confirm: (name) => `Удалить ${name}?`, + deleted: 'Удалено ', + delete_failed: 'Не удалось удалить: ', + new_file_prompt: 'Имя нового файла (например, notes.md):', + project_name_prompt: 'Имя проекта:', + created: 'Создано ', + create_failed: 'Не удалось создать: ', + new_folder_prompt: 'Имя новой папки:', + folder_created: 'Папка создана ', + folder_create_failed: 'Не удалось создать папку: ', + remove_title: 'Удаление', + empty_dir: '(пусто)', + upload_failed: 'Не удалось загрузить: ', + all_uploads_failed: (n) => `Не удалось загрузить все ${n} файлов`, + settings_title: 'Настройки', + settings_save_btn: 'Сохранить настройки', + settings_label_model: 'Модель по умолчанию', + settings_label_send_key: 'Клавиша отправки', + settings_label_theme: 'Тема', + settings_label_language: 'Язык', + settings_label_token_usage: 'Показывать использование токенов', + settings_label_bubble_layout: 'Раскладка пузырьков чата', + settings_label_cli_sessions: 'Показывать сеансы агента', + settings_label_sync_insights: 'Синхронизировать с Insights', + settings_label_check_updates: 'Проверять обновления', + settings_label_bot_name: 'Имя помощника', + settings_label_password: 'Пароль доступа', + settings_saved: 'Настройки сохранены', + settings_save_failed: 'Не удалось сохранить: ', + settings_load_failed: 'Не удалось загрузить настройки: ', + settings_saved_pw: 'Настройки сохранены (пароль задан — теперь требуется вход)', + settings_saved_pw_updated: 'Настройки сохранены (пароль обновлён)', + login_title: 'Вход', + login_subtitle: 'Введите пароль, чтобы продолжить', + login_placeholder: 'Пароль', + login_btn: 'Войти', + login_invalid_pw: 'Неверный пароль', + login_conn_failed: 'Не удалось подключиться', + tab_chat: 'Чат', + tab_tasks: 'Задачи', + tab_skills: 'Навыки', + tab_memory: 'Память', + tab_workspaces: 'Рабочие пространства', + tab_profiles: 'Профили', + tab_todos: 'Список дел', + new_conversation: 'Новая беседа', + filter_conversations: 'Фильтр бесед...', + session_time_unknown: 'Неизвестно', + session_time_just_now: 'только что', + session_time_minutes_ago: (n) => { + const mod10 = n % 10; + const mod100 = n % 100; + const word = mod10 === 1 && mod100 !== 11 + ? 'минута' + : (mod10 >= 2 && mod10 <= 4 && (mod100 < 10 || mod100 >= 20) + ? 'минуты' + : 'минут'); + return `${n} ${word} назад`; + }, + session_time_hours_ago: (n) => { + const mod10 = n % 10; + const mod100 = n % 100; + const word = mod10 === 1 && mod100 !== 11 + ? 'час' + : (mod10 >= 2 && mod10 <= 4 && (mod100 < 10 || mod100 >= 20) + ? 'часа' + : 'часов'); + return `${n} ${word} назад`; + }, + session_time_days_ago: (n) => { + const mod10 = n % 10; + const mod100 = n % 100; + const word = mod10 === 1 && mod100 !== 11 + ? 'день' + : (mod10 >= 2 && mod10 <= 4 && (mod100 < 10 || mod100 >= 20) + ? 'дня' + : 'дней'); + return `${n} ${word} назад`; + }, + session_time_last_week: 'на прошлой неделе', + session_time_bucket_today: 'Сегодня', + session_time_bucket_yesterday: 'Вчера', + session_time_bucket_this_week: 'На этой неделе', + session_time_bucket_last_week: 'На прошлой неделе', + session_time_bucket_older: 'Ранее', + scheduled_jobs: 'Запланированные задания', + new_job: 'Новое задание', + loading: 'Загрузка...', + search_skills: 'Поиск навыков...', + new_skill: 'Новый навык', + personal_memory: 'Личная память', + current_task_list: 'Текущий список задач', + workspace_desc: 'Добавляйте рабочие пространства и переключайтесь между ними в своих сеансах.', + new_profile: 'Новый профиль', + transcript: 'Транскрипт', + download_transcript: 'Скачать как Markdown', + import: 'Импорт', + settings_label_sound: 'Звук уведомления', + settings_desc_sound: 'Проигрывать звук, когда помощник завершает ответ.', + settings_label_notifications: 'Уведомления браузера', + settings_desc_notifications: 'Показывать системное уведомление, когда ответ готов, а вкладка находится в фоне.', + settings_desc_token_usage: 'Показывает количество входных и выходных токенов под каждым ответом помощника. Также переключается через /usage.', + settings_desc_bubble_layout: 'Выравнивает сообщения пользователя справа, а ответы помощника слева. Выключено по умолчанию, чтобы блоки кода и вывод инструментов занимали всю ширину.', + settings_desc_cli_sessions: 'Объединяет сеансы из Hermes CLI (state.db) в список сеансов. Нажмите на CLI-сеанс, чтобы импортировать его и продолжить разговор.', + settings_desc_sync_insights: 'Синхронизирует использование токенов WebUI в state.db, чтобы Hermes /insights включал данные браузерных сеансов. Выключено по умолчанию.', + settings_desc_check_updates: 'Показывает баннер, когда доступны более новые версии WebUI или Agent. Периодически выполняет git fetch в фоне.', + settings_desc_bot_name: 'Отображаемое имя помощника во всём интерфейсе. По умолчанию Hermes.', + settings_desc_password: 'Введите новый пароль, чтобы задать или изменить его. Оставьте пустым, чтобы сохранить текущую настройку.', + password_placeholder: 'Введите новый пароль…', + disable_auth: 'Отключить авторизацию', + sign_out: 'Выйти', + cancel: 'Отмена', + create_job: 'Создать задание', + save_skill: 'Сохранить навык', + editing: 'Редактирование', + empty_title: 'Чем я могу помочь?', + empty_subtitle: 'Спрашивайте что угодно, запускайте команды, изучайте файлы или управляйте запланированными задачами.', + suggest_files: 'Какие файлы есть в этом рабочем пространстве?', + suggest_schedule: 'Что у меня сегодня в расписании?', + suggest_plan: 'Помоги спланировать небольшой проект.', + onboarding_badge: 'ПЕРВЫЙ ЗАПУСК', + onboarding_title: 'Добро пожаловать в Hermes Web UI', + onboarding_lead: 'Краткая пошаговая настройка проверит Hermes, сохранит рабочую конфигурацию провайдера, выберет рабочее пространство и модель и при желании защитит приложение паролем.', + onboarding_back: 'Назад', + onboarding_continue: 'Продолжить', + onboarding_skip: 'Пропустить настройку', + onboarding_skipped: 'Настройка пропущена — используется существующая конфигурация.', + onboarding_open: 'Открыть Hermes', + onboarding_step_system_title: 'Проверка системы', + onboarding_step_system_desc: 'Проверить Hermes Agent и видимость конфигурации.', + onboarding_step_setup_title: 'Настройка провайдера', + onboarding_step_setup_desc: 'Сохранить минимальную рабочую конфигурацию провайдера Hermes.', + onboarding_step_workspace_title: 'Рабочее пространство и модель', + onboarding_step_workspace_desc: 'Выбрать значения по умолчанию для новых сеансов и чатов.', + onboarding_step_password_title: 'Необязательный пароль', + onboarding_step_password_desc: 'Защитить Web UI перед тем, как делиться им.', + onboarding_step_finish_title: 'Готово', + onboarding_step_finish_desc: 'Проверьте настройки и войдите в приложение.', + onboarding_notice_system_ready: 'Hermes Agent, похоже, доступен из Web UI.', + onboarding_notice_system_unavailable: 'Hermes Agent ещё не полностью доступен. Bootstrap может установить его, но для настройки провайдера всё ещё может понадобиться терминал.', + onboarding_check_agent: 'Hermes Agent', + onboarding_check_agent_ready: 'Обнаружен и доступен для импорта', + onboarding_check_agent_missing: 'Отсутствует или доступен только частично', + onboarding_check_password: 'Пароль', + onboarding_check_password_enabled: 'Уже включён', + onboarding_check_password_disabled: 'Пока не включён', + onboarding_check_provider: 'Конфигурация провайдера', + onboarding_check_provider_ready: 'Готова к чату', + onboarding_check_provider_partial: 'Сохранена, но не завершена', + onboarding_check_provider_pending: 'Требует проверки', + onboarding_config_file: 'Файл конфигурации:', + onboarding_env_file: 'Файл .env:', + onboarding_unknown: 'Неизвестно', + onboarding_current_provider: 'Текущая конфигурация:', + onboarding_missing_imports: 'Отсутствующие импорты:', + onboarding_notice_setup_required: 'Выберите здесь простой путь настройки провайдера. Продвинутые OAuth-сценарии пока остаются в Hermes CLI.', + onboarding_notice_setup_already_ready: 'Уже обнаружена рабочая конфигурация провайдера Hermes. Вы можете оставить её или заменить здесь.', + onboarding_oauth_provider_ready_title: 'Провайдер уже авторизован', + onboarding_oauth_provider_ready_body: 'Этот экземпляр настроен на использование OAuth-провайдера ({provider}), настроенного через Hermes CLI. API-ключ здесь не нужен — нажмите «Продолжить», чтобы завершить настройку.', + onboarding_oauth_provider_not_ready_title: 'OAuth-провайдер ещё не авторизован', + onboarding_oauth_provider_not_ready_body: 'Этот экземпляр настроен на использование {provider}, который работает через OAuth, а не через API-ключ. Запустите hermes auth или hermes model в терминале, чтобы пройти авторизацию, затем обновите Web UI.', + onboarding_oauth_switch_hint: 'Или выберите ниже другой провайдер, чтобы перейти на настройку с ключом API:', + onboarding_notice_workspace: 'Эти значения используют те же API настроек, что и обычное приложение.', + onboarding_workspace_label: 'Рабочее пространство', + onboarding_workspace_or_path: 'Или укажите путь к рабочему пространству', + onboarding_workspace_placeholder: '/home/you/workspace', + onboarding_provider_label: 'Режим настройки', + onboarding_quick_setup_badge: 'Быстрая настройка', + onboarding_api_key_label: 'Ключ API', + onboarding_api_key_placeholder: 'Оставьте пустым, чтобы сохранить уже сохранённый ключ', + onboarding_api_key_help_prefix: 'Сохраняется как секрет в вашем файле `.env` Hermes с помощью', + onboarding_base_url_label: 'Базовый URL', + onboarding_base_url_placeholder: 'https://your-endpoint.example/v1', + onboarding_base_url_help: 'Используйте это для OpenAI-compatible маршрутизаторов, self-hosted серверов, LiteLLM, Ollama, LM Studio, vLLM и похожих endpoint-ов.', + onboarding_model_label: 'Модель по умолчанию', + onboarding_workspace_help: 'Выберите модель, которую Hermes должен использовать для новых чатов после завершения настройки.', + onboarding_custom_model_placeholder: 'имя_вашей_модели', + onboarding_custom_model_help: 'Для собственных endpoint-ов укажите точный ID модели, который ожидает ваш сервер.', + onboarding_notice_password_enabled: 'Пароль уже настроен. Вводите новый только если хотите заменить текущий.', + onboarding_notice_password_recommended: 'Необязательно, но рекомендуется, если вы собираетесь открывать UI не только на localhost.', + onboarding_password_label: 'Пароль (необязательно)', + onboarding_password_placeholder: 'Оставьте пустым, чтобы пропустить', + onboarding_password_help: 'Пароли сохраняются через существующий API настроек и хэшируются на сервере.', + onboarding_notice_finish: 'Позже вы сможете снова открыть настройки и изменить любое из этих значений.', + onboarding_not_set: 'Не задано', + onboarding_password_will_enable: 'Будет включён', + onboarding_password_will_replace: 'Будет заменён текущий пароль', + onboarding_password_keep_existing: 'Оставить текущий пароль', + onboarding_password_remains_disabled: 'Останется отключённым', + onboarding_password_skipped: 'Пропустить пока', + onboarding_finish_help: 'После завершения в настройках сохранится onboarding_completed, и вы попадёте в обычное приложение.', + onboarding_error_choose_workspace: 'Выберите рабочее пространство перед продолжением.', + onboarding_error_choose_model: 'Выберите модель перед продолжением.', + onboarding_error_provider_required: 'Выберите режим настройки перед продолжением.', + onboarding_error_base_url_required: 'Для собственных endpoint-ов требуется базовый URL.', + onboarding_error_workspace_required: 'Рабочее пространство обязательно.', + onboarding_error_model_required: 'Модель обязательна.', + onboarding_complete: 'Первичная настройка завершена', + error_prefix: 'Ошибка: ', + not_available: 'н/д', + never: 'никогда', + add: 'Добавить', + add_failed: 'Не удалось добавить: ', + remove_failed: 'Не удалось удалить: ', + switch_failed: 'Не удалось переключить: ', + name_required: 'Требуется имя', + content_required: 'Требуется содержимое', + view: 'Просмотр', + dismiss: 'Скрыть', + disable: 'Отключить', + cron_no_jobs: 'Запланированные задания не найдены.', + cron_status_off: 'неактивно', + cron_status_paused: 'на паузе', + cron_status_error: 'ошибка', + cron_status_active: 'активно', + cron_next: 'Следующий', + cron_last: 'Последний', + cron_run_now: 'Запустить сейчас', + cron_pause: 'Пауза', + cron_resume: 'Возобновить', + cron_job_name_placeholder: 'Имя задания', + cron_schedule_placeholder: 'Расписание', + cron_prompt_placeholder: 'Промпт', + cron_last_output: 'Последний вывод', + cron_all_runs: 'Все запуски', + cron_hide_runs: 'Скрыть запуски', + cron_no_runs_yet: '(пока запусков нет)', + cron_schedule_required_example: 'Требуется расписание (например, "0 9 * * *" или "every 1h")', + cron_schedule_required: 'Требуется расписание', + cron_prompt_required: 'Требуется промпт', + cron_job_created: 'Задание создано', + cron_job_triggered: 'Задание запущено', + cron_job_paused: 'Задание поставлено на паузу', + cron_job_resumed: 'Задание возобновлено', + cron_job_updated: 'Задание обновлено', + cron_delete_confirm_title: 'Удалить cron-задание', + cron_delete_confirm_message: 'Это действие нельзя отменить.', + cron_job_deleted: 'Задание удалено', + cron_completion_status: (name, status) => `Cron-задание «${name}» — ${status}`, + status_failed: 'неудачно', + status_completed: 'завершено', + todos_no_active: 'В этой сессии нет активного списка задач.', + clear_conversation_title: 'Очистить беседу', + clear_conversation_message: 'Очистить все сообщения? Это действие нельзя отменить.', + clear_failed: 'Не удалось очистить: ', + skills_no_match: 'Подходящих навыков не найдено.', + linked_files: 'Связанные файлы', + skill_load_failed: 'Не удалось загрузить навык: ', + skill_file_load_failed: 'Не удалось загрузить файл: ', + skill_name_required: 'Требуется имя навыка', + skill_updated: 'Навык обновлён', + skill_created: 'Навык создан', + memory_notes_label: 'память (заметки)', + memory_saved: 'Память сохранена', + my_notes: 'Мои заметки', + user_profile: 'Пользовательский профиль', + no_notes_yet: 'Пока нет заметок.', + no_profile_yet: 'Пока нет профиля.', + workspace_choose_path: 'Выберите путь к рабочему пространству', + workspace_choose_path_meta: 'Добавьте проверенный путь и переключите эту беседу', + workspace_manage: 'Управление рабочими пространствами', + workspace_manage_meta: 'Открыть панель Spaces', + workspace_use_title: 'Использовать в текущем сеансе', + workspace_use: 'Использовать', + workspace_add_path_placeholder: 'Добавьте путь к рабочему пространству (например, /Users/you/project)', + workspace_paths_validated_hint: 'Перед сохранением пути проверяются на существование.', + workspace_added: 'Рабочее пространство добавлено', + workspace_remove_confirm_title: 'Удалить рабочее пространство', + workspace_remove_confirm_message: (path) => `Удалить «${path}»?`, + workspace_removed: 'Рабочее пространство удалено', + workspace_switch_prompt_title: 'Переключить рабочее пространство', + workspace_switch_prompt_message: 'Введите абсолютный путь к рабочему пространству, чтобы добавить его и переключить эту беседу.', + workspace_switch_prompt_confirm: 'Переключить', + workspace_switch_prompt_placeholder: '/Users/you/project', + workspace_not_added: 'Рабочее пространство не добавлено', + workspace_already_saved: 'Рабочее пространство уже сохранено — выберите его из списка', + workspace_busy_switch: 'Нельзя переключать рабочее пространство, пока агент работает', + discard_file_edits_title: 'Отменить изменения файлов?', + discard_file_edits_message: 'При переключении рабочих пространств несохранённые изменения в предпросмотре будут потеряны.', + workspace_switched_to: (name) => `Переключено на ${name}`, + profiles_no_profiles: 'Профили не найдены.', + profile_api_keys_configured: 'API-ключи настроены', + profile_gateway_running: 'Gateway запущен', + profile_gateway_stopped: 'Gateway остановлен', + profile_active: 'АКТИВЕН', + profile_no_configuration: 'Нет конфигурации', + profile_skill_count: (count) => { + const mod10 = count % 10; + const mod100 = count % 100; + const word = mod10 === 1 && mod100 !== 11 + ? 'навык' + : (mod10 >= 2 && mod10 <= 4 && (mod100 < 10 || mod100 >= 20) + ? 'навыка' + : 'навыков'); + return `${count} ${word}`; + }, + profile_use: 'Использовать', + profile_switch_title: 'Переключиться на этот профиль', + profile_delete_title: 'Удалить этот профиль', + profile_default_label: '(по умолчанию)', + profile_name_placeholder: 'Название профиля (строчные буквы, a-z, 0-9, дефисы)', + profile_clone_label: 'Скопировать конфигурацию из активного профиля', + profile_base_url_placeholder: 'Базовый URL (необязательно, например http://localhost:11434)', + profile_api_key_placeholder: 'API-ключ (необязательно)', + manage_profiles: 'Управление профилями', + profiles_load_failed: 'Не удалось загрузить профили', + profiles_busy_switch: 'Нельзя переключать профили, пока агент работает', + profile_switched_new_conversation: (name) => `Переключено на профиль: ${name} — начата новая беседа`, + profile_switched: (name) => `Переключено на профиль: ${name}`, + profile_name_rule: 'Только строчные буквы, цифры, дефисы и подчёркивания', + profile_base_url_rule: 'Базовый URL должен начинаться с http:// или https://', + profile_created: (name) => `Профиль создан: ${name}`, + profile_delete_confirm_title: (name) => `Удалить профиль «${name}»?`, + profile_delete_confirm_message: 'Это удалит всю конфигурацию, навыки, память и сеансы этого профиля.', + profile_deleted: (name) => `Профиль удалён: ${name}`, + active_conversation_none: 'Активная беседа не выбрана.', + active_conversation_meta: (title, count) => { + const mod10 = count % 10; + const mod100 = count % 100; + const word = mod10 === 1 && mod100 !== 11 + ? 'сообщение' + : (mod10 >= 2 && mod10 <= 4 && (mod100 < 10 || mod100 >= 20) + ? 'сообщения' + : 'сообщений'); + return `${title} · ${count} ${word}`; + }, + settings_unsaved_changes: 'У вас есть несохранённые изменения.', + sign_out_failed: 'Не удалось выйти: ', + disable_auth_confirm_title: 'Отключить защиту паролем', + disable_auth_confirm_message: 'Любой сможет получить доступ к этому экземпляру.', + auth_disabled: 'Авторизация отключена — защита паролем снята', + disable_auth_failed: 'Не удалось отключить авторизацию: ', + bg_error_single: (title) => `В "${title}" возникла ошибка`, + bg_error_multi: (count) => `${count} сеансов столкнулись с ошибкой`, + }, + es: { _lang: 'es', _label: 'Español', @@ -534,6 +998,7 @@ const LOCALES = { cmd_clear: 'Borrar los mensajes de la conversación', cmd_compress: 'Comprimir manualmente el contexto de la conversación (uso: /compress [tema])', cmd_compact_alias: 'Alias antiguo de /compress', + cmd_compact: 'Comprimir contexto de la conversación', cmd_model: 'Cambiar de modelo (p. ej. /model gpt-4o)', cmd_workspace: 'Cambiar de espacio de trabajo por nombre', cmd_new: 'Iniciar una nueva sesión de chat', @@ -869,6 +1334,11 @@ const LOCALES = { profile_use: 'Use', profile_switch_title: 'Switch to this profile', profile_delete_title: 'Eliminar este perfil', + profile_default_label: '(predeterminado)', + profile_name_placeholder: 'Nombre del perfil (minúsculas, a-z, 0-9, guiones)', + profile_clone_label: 'Clonar configuración del perfil activo', + profile_base_url_placeholder: 'URL base (opcional, p. ej. http://localhost:11434)', + profile_api_key_placeholder: 'Clave API (opcional)', manage_profiles: 'Manage profiles', profiles_load_failed: 'Failed to load profiles', profiles_busy_switch: 'Cannot switch profiles while agent is running', @@ -1508,6 +1978,11 @@ const LOCALES = { profile_use: '使用', profile_switch_title: '切换到此配置档', profile_delete_title: '删除此配置档', + profile_default_label: '(默认)', + profile_name_placeholder: '配置档名称(小写字母、a-z、0-9、连字符)', + profile_clone_label: '复制当前配置档的配置', + profile_base_url_placeholder: 'Base URL(可选,例如 http://localhost:11434)', + profile_api_key_placeholder: 'API 密钥(可选)', manage_profiles: '管理配置档', profiles_load_failed: '加载配置档失败', profiles_busy_switch: 'Agent 运行中,无法切换配置档', diff --git a/static/index.html b/static/index.html index 6877e70..3a0be2c 100644 --- a/static/index.html +++ b/static/index.html @@ -127,19 +127,19 @@ -
Loading...
+
Loading...