@@ -460,7 +460,9 @@ if (SENTRY_URL := env.str('SENTRY_URL', '')) and RELEASE and ENVIRONMENT: 'PromptLengthExceeded', 'InvalidParameterError', 'UnsupportedSize', + 'OutputSensitiveContentError', 'OutputSensitiveImageContentError', + 'OutputSensitiveVideoContentError', 'InputImageSensitiveContentError', ], ) @@ -2,13 +2,13 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-08-13 17:52+0300\n" +"POT-Creation-Date: 2026-08-17 18:52+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -194,8 +194,8 @@ msgid "Child Business Accounts" msgstr "Дочерние Бизнес Аккаунты" #: authentication/models/business_group.py:8 ml_model/models.py:19 -#: ml_model/models.py:39 ml_model/models.py:63 ml_model/models.py:279 -#: tools/chats/models.py:9 tools/media/models.py:59 tools/media/models.py:95 +#: ml_model/models.py:39 ml_model/models.py:63 ml_model/models.py:285 +#: tools/chats/models.py:9 tools/media/models.py:58 tools/media/models.py:94 msgid "Title" msgstr "Название" @@ -213,7 +213,7 @@ msgstr "Бизнес Группы" #: authentication/models/user_vk.py:12 payments/admin.py:41 #: payments/admin.py:178 payments/models/invoice.py:15 #: payments/models/payment.py:26 payments/models/payment_plan.py:42 -#: tools/media/models.py:108 +#: tools/media/models.py:107 msgid "User" msgstr "Пользователь" @@ -222,7 +222,7 @@ msgid "Affiliated by" msgstr "Кем привлечена" #: authentication/models/business_host.py:36 authentication/models/user.py:135 -#: authentication/models/whitelist.py:16 ml_model/models.py:177 +#: authentication/models/whitelist.py:16 ml_model/models.py:183 #: payments/models/promocode.py:85 msgid "Is active" msgstr "Является активной" @@ -263,7 +263,7 @@ msgstr "ИНН" msgid "PSRN" msgstr "ОГРН" -#: authentication/models/business_host.py:77 ml_model/models.py:190 +#: authentication/models/business_host.py:77 ml_model/models.py:196 #: tools/public_api/models.py:31 tools/public_api/services/api_key.py:24 msgid "Name" msgstr "Наименование" @@ -368,15 +368,15 @@ msgstr "Админ" msgid "Security" msgstr "Безопасность" -#: authentication/models/email_token.py:16 ml_model/models.py:281 +#: authentication/models/email_token.py:16 ml_model/models.py:287 msgid "Key" msgstr "Ключ" -#: authentication/models/email_token.py:22 +#: authentication/models/email_token.py:20 msgid "Email Token" msgstr "Email Токен" -#: authentication/models/email_token.py:23 +#: authentication/models/email_token.py:21 msgid "Email Tokens" msgstr "Email Токены" @@ -550,15 +550,15 @@ msgstr "" msgid "Host user is not registered for this account" msgstr "Пользователь бизнес-аккаунта не зарегистрирован для этого аккаунта" -#: authentication/selectors/user_selector.py:77 +#: authentication/selectors/user_selector.py:76 msgid "No user with this uid found" msgstr "Не найден пользователь с данным ID" -#: authentication/services/business_account_service.py:57 +#: authentication/services/business_account_service.py:56 msgid "BusinessAccount for this user doesn't exist" msgstr "Бизнес-аккаунт для данного юзера не найден" -#: authentication/services/business_account_service.py:71 +#: authentication/services/business_account_service.py:70 msgid "Invited account can either accept or reject an invitation" msgstr "Приглашенный аккаунт может принять или отклонить приглашение" @@ -637,7 +637,7 @@ msgstr "Уже существует %(model)s с полями %(fields)s" msgid "Invalid JSON payload" msgstr "Некорректный JSON" -#: messages/serializers.py:44 ml_model/exceptions.py:89 +#: messages/serializers.py:45 ml_model/exceptions.py:91 #: tools/chats/schemas.py:23 #, python-format msgid "The file size cannot exceed %(max_mb_size)d MB" @@ -648,20 +648,20 @@ msgstr "Файл не может быть размером больше %(max_mb msgid "Version %(version)s already has input with the same type: %(type)s" msgstr "Версия %(version)s уже имеет входные данные с таким же типом: %(type)s" -#: ml_model/apps.py:9 ml_model/models.py:158 +#: ml_model/apps.py:9 ml_model/models.py:164 msgid "Neuron Models" msgstr "Нейронные Модели" -#: ml_model/exceptions.py:21 +#: ml_model/exceptions.py:23 msgid "The model is currently disabled. Please try again later." msgstr "" "Модель в настоящее время неактивна. Пожалуйста, повторите попытку позже." -#: ml_model/exceptions.py:26 +#: ml_model/exceptions.py:28 msgid "Your request was blocked by our moderation system" msgstr "Ваш запрос был заблокирован нашей системой модерации" -#: ml_model/exceptions.py:36 +#: ml_model/exceptions.py:38 #, python-format msgid "" "Image size %(cw)dx%(ch)d is not supported. Please rotate image to " @@ -670,25 +670,25 @@ msgstr "" "Размер изображения %(cw)dx%(ch)d не поддерживается. Пожалуйста, переверните " "до %(rw)dx%(rh)d" -#: ml_model/exceptions.py:39 +#: ml_model/exceptions.py:41 #, python-format msgid "Image size %(cw)sx%(ch)s is not supported. Required size: %(rw)sx%(rh)s" msgstr "" "Размер изображения %(cw)sx%(ch)s не поддерживается. Требуемый размер: " "%(rw)sx%(rh)s" -#: ml_model/exceptions.py:49 +#: ml_model/exceptions.py:51 #, python-format msgid "Image exceeds the maximum allowed pixel count (%(max_pixels)d)." msgstr "" "Размер изображения превышает максимально допустимое количество пикселей " "(%(max_pixels)d)." -#: ml_model/exceptions.py:56 +#: ml_model/exceptions.py:58 msgid "The model is not responding" msgstr "Модель не отвечает" -#: ml_model/exceptions.py:65 +#: ml_model/exceptions.py:67 #, python-format msgid "" "The attached file format is not supported. Available formats: " @@ -697,109 +697,112 @@ msgstr "" "Формат вложенного файла не поддерживается. Доступные форматы: " "%(available_extensions)s." -#: ml_model/exceptions.py:71 +#: ml_model/exceptions.py:73 msgid "The file may be corrupted. Please try another one." msgstr "Возможно, файл повреждён. Попробуйте загрузить другой файл." -#: ml_model/exceptions.py:76 +#: ml_model/exceptions.py:78 msgid "File Uploading Not supported" msgstr "Загрузка файлов не поддерживается" -#: ml_model/exceptions.py:81 +#: ml_model/exceptions.py:83 msgid "Unable to recognize the file" msgstr "Не удаётся распознать файл" -#: ml_model/exceptions.py:94 +#: ml_model/exceptions.py:96 msgid "The length of the context has been exceeded." msgstr "Длина контекста превышена." -#: ml_model/exceptions.py:99 +#: ml_model/exceptions.py:101 msgid "Jinja template not found" msgstr "Jinja-шаблон не найден" -#: ml_model/exceptions.py:104 +#: ml_model/exceptions.py:106 msgid "There was an unknown error while rendering a template" msgstr "При рендеринге шаблона произошла неизвестная ошибка" -#: ml_model/exceptions.py:109 +#: ml_model/exceptions.py:111 msgid "The neuron model does not exist" msgstr "Нейронная модель не существует" -#: ml_model/exceptions.py:117 +#: ml_model/exceptions.py:119 #, python-format msgid "The %(file_type)s is not attached" msgstr "Файл (%(file_type)s) не прикреплен" -#: ml_model/exceptions.py:122 +#: ml_model/exceptions.py:124 msgid "No image content found in response. Try a different request" msgstr "В промпте отсутствует описание изображения. Попробуйте другой запрос" -#: ml_model/exceptions.py:127 +#: ml_model/exceptions.py:129 msgid "" "The model could not analyze your request. Please rephrase it and try again" msgstr "" "Модель не смогла проанализировать ваш запрос. Перефразируйте его и " "попробуйте снова" -#: ml_model/exceptions.py:132 +#: ml_model/exceptions.py:134 msgid "Image analysis error. Please try another image." msgstr "Ошибка анализа изображения. Попробуйте другую картинку." -#: ml_model/exceptions.py:137 +#: ml_model/exceptions.py:139 msgid "Use style type AUTO or GENERAL when a style preset is selected" msgstr "При выбранном стиле используйте тип стиля AUTO или GENERAL" -#: ml_model/exceptions.py:142 +#: ml_model/exceptions.py:144 msgid "Prediction interrupted. Please retry again" msgstr "Генерация прервана. Пожалуйста, повторите попытку еще раз" -#: ml_model/exceptions.py:159 +#: ml_model/exceptions.py:161 #, python-format msgid "Prompt is too long. Maximum length is %(max_length)s characters." msgstr "Промпт слишком длинный. Максимальная длина — %(max_length)s символов." -#: ml_model/exceptions.py:162 +#: ml_model/exceptions.py:164 msgid "Prompt is too long" msgstr "Промпт слишком длинный" -#: ml_model/exceptions.py:167 +#: ml_model/exceptions.py:169 msgid "" "Service is currently unavailable due to high demand. Please try again later" msgstr "" "Сервис временно недоступен из-за высокой нагрузки. Пожалуйста, попробуйте " "позже" -#: ml_model/exceptions.py:172 +#: ml_model/exceptions.py:174 msgid "Service is temporarily unavailable. Please try again later" msgstr "Сервис временно недоступен. Пожалуйста, попробуйте позже" -#: ml_model/exceptions.py:192 +#: ml_model/exceptions.py:194 #, python-format msgid "%(feature)s is available only in paid plan." msgstr "%(feature)s доступно только в платном тарифном плане." -#: ml_model/exceptions.py:199 +#: ml_model/exceptions.py:201 msgid "Face not found in the image. Please try another image with a face." msgstr "Не найдено лицо на картинке. Попробуйте другую картинку с лицом." -#: ml_model/exceptions.py:204 +#: ml_model/exceptions.py:206 msgid "The input image may contain real person." msgstr "Загруженное изображение может содержать реального человека." -#: ml_model/exceptions.py:209 -msgid "The generated image may contain private or prohibited content" -msgstr "Готовое изображение может содержать приватный или запрещённый контент" +#: ml_model/exceptions.py:213 +#, python-format +msgid "" +"The generated %(content_type)s may contain private or prohibited content" +msgstr "" +"Готовое %(content_type)s может содержать приватный или запрещённый контент" -#: ml_model/exceptions.py:214 +#: ml_model/exceptions.py:228 msgid "The input image may contain private or prohibited content" msgstr "" "Загруженное изображение может содержать приватный или запрещённый контент" -#: ml_model/exceptions.py:223 +#: ml_model/exceptions.py:237 msgid "not specified" msgstr "не указана" -#: ml_model/exceptions.py:224 +#: ml_model/exceptions.py:238 #, python-format msgid "" "Version \"%(version)s\" is not available. Available versions: " @@ -812,7 +815,7 @@ msgid "Redis is unavailable" msgstr "Redis недоступен" #: ml_model/models.py:20 ml_model/models.py:40 ml_model/models.py:72 -#: ml_model/models.py:192 tools/media/models.py:67 +#: ml_model/models.py:198 tools/media/models.py:66 msgid "Slug" msgstr "Ярлык" @@ -844,7 +847,7 @@ msgstr "Теги модели" msgid "Alternative Titles" msgstr "Альтернативные названия" -#: ml_model/models.py:70 ml_model/models.py:191 ml_model/models.py:280 +#: ml_model/models.py:70 ml_model/models.py:197 ml_model/models.py:286 #: payments/models/payment.py:52 msgid "Description" msgstr "Описание" @@ -861,236 +864,236 @@ msgstr "Аватар" msgid "Tags" msgstr "Теги" -#: ml_model/models.py:157 payments/models/payment_plan_feature.py:18 +#: ml_model/models.py:163 payments/models/payment_plan_feature.py:19 msgid "Neuron Model" msgstr "Нейронная Модель" -#: ml_model/models.py:166 ml_model/models.py:413 payments/admin.py:184 +#: ml_model/models.py:172 ml_model/models.py:419 payments/admin.py:184 msgid "Model" msgstr "Модель" -#: ml_model/models.py:182 ml_model/models.py:183 +#: ml_model/models.py:188 ml_model/models.py:189 msgid "Settings" msgstr "Настройки" -#: ml_model/models.py:186 +#: ml_model/models.py:192 #, python-format msgid "Settings of %(model_title)s" msgstr "Настройки %(model_title)s" -#: ml_model/models.py:205 +#: ml_model/models.py:211 #, python-format msgid "%(model_title)s | %(version_name)s" msgstr "%(model_title)s | %(version_name)s" -#: ml_model/models.py:211 +#: ml_model/models.py:217 msgid "Model Version" msgstr "Версия Модели" -#: ml_model/models.py:212 +#: ml_model/models.py:218 msgid "Model Versions" msgstr "Версии Модели" -#: ml_model/models.py:221 +#: ml_model/models.py:227 msgid "Versions" msgstr "Версии" -#: ml_model/models.py:222 +#: ml_model/models.py:228 msgid "Link to versions" msgstr "Привязка к версиям" -#: ml_model/models.py:231 +#: ml_model/models.py:237 msgid "Text" msgstr "Текст" -#: ml_model/models.py:232 +#: ml_model/models.py:238 msgid "Image" msgstr "Картинка" -#: ml_model/models.py:233 +#: ml_model/models.py:239 msgid "PDF" msgstr "PDF" -#: ml_model/models.py:234 +#: ml_model/models.py:240 msgid "DOCX" msgstr "DOCX" -#: ml_model/models.py:235 +#: ml_model/models.py:241 msgid "DOC" msgstr "DOC" -#: ml_model/models.py:236 +#: ml_model/models.py:242 msgid "Text File (Notebook)" msgstr "Текстовый файл (Блокнот)" -#: ml_model/models.py:237 +#: ml_model/models.py:243 msgid "ZIP Archive" msgstr "ZIP архив" -#: ml_model/models.py:238 payments/tests/test_plans.py:35 +#: ml_model/models.py:244 payments/tests/test_plans.py:35 msgid "Audio" msgstr "Аудио" -#: ml_model/models.py:239 payments/tests/test_plans.py:31 +#: ml_model/models.py:245 payments/tests/test_plans.py:31 msgid "Video" msgstr "Видео" -#: ml_model/models.py:245 ml_model/models.py:283 +#: ml_model/models.py:251 ml_model/models.py:289 #: payments/models/promocode.py:41 msgid "Type" msgstr "Тип" -#: ml_model/models.py:247 ml_model/models.py:294 +#: ml_model/models.py:253 ml_model/models.py:300 msgid "Required" msgstr "Обязательный" -#: ml_model/models.py:250 +#: ml_model/models.py:256 #, python-format msgid "%(model_title)s | %(input_type)s" msgstr "%(model_title)s | %(input_type)s" -#: ml_model/models.py:256 +#: ml_model/models.py:262 msgid "Model Input" msgstr "Модель" -#: ml_model/models.py:257 +#: ml_model/models.py:263 msgid "Model Inputs" msgstr "Входящий поток модели" -#: ml_model/models.py:262 +#: ml_model/models.py:268 msgid "Integer" msgstr "Целое число" -#: ml_model/models.py:263 +#: ml_model/models.py:269 msgid "Float" msgstr "Вещественное число" -#: ml_model/models.py:264 +#: ml_model/models.py:270 msgid "String" msgstr "Строка" -#: ml_model/models.py:267 +#: ml_model/models.py:273 msgid "List" msgstr "Список" -#: ml_model/models.py:271 +#: ml_model/models.py:277 msgid "Float range" msgstr "Вещественный диапазон" -#: ml_model/models.py:275 +#: ml_model/models.py:281 msgid "Integer range" msgstr "Целочисленный диапазон" -#: ml_model/models.py:277 +#: ml_model/models.py:283 msgid "Logical" msgstr "Логический" -#: ml_model/models.py:290 +#: ml_model/models.py:296 msgid "Values" msgstr "Значения" -#: ml_model/models.py:291 +#: ml_model/models.py:297 msgid "" "These values can contain different interfaces and default value optional" msgstr "" "Значения могут содержать различные интерфейс и, опционально, значение по " "умолчанию" -#: ml_model/models.py:293 +#: ml_model/models.py:299 msgid "Hidden" msgstr "Скрытый" -#: ml_model/models.py:299 +#: ml_model/models.py:305 #, python-format msgid "Parameter of %(model_title)s" msgstr "Параметр %(model_title)s" -#: ml_model/models.py:302 +#: ml_model/models.py:308 msgid "Parameter" msgstr "Параметр" -#: ml_model/models.py:303 +#: ml_model/models.py:309 msgid "Parameters" msgstr "Параметры" -#: ml_model/models.py:308 +#: ml_model/models.py:314 msgid "Fixed" msgstr "Фикса" -#: ml_model/models.py:309 +#: ml_model/models.py:315 msgid "Per generation second" msgstr "За секунду генерации" -#: ml_model/models.py:310 +#: ml_model/models.py:316 msgid "Per one text token" msgstr "За один текстовый токен" -#: ml_model/models.py:311 +#: ml_model/models.py:317 msgid "Per image pixel" msgstr "За один пиксель" -#: ml_model/models.py:314 +#: ml_model/models.py:320 msgid "By input data" msgstr "По входящим данным" -#: ml_model/models.py:315 +#: ml_model/models.py:321 msgid "By output data" msgstr "По исходящим данным" -#: ml_model/models.py:316 +#: ml_model/models.py:322 msgid "By all data" msgstr "По всем данным" -#: ml_model/models.py:321 +#: ml_model/models.py:327 msgid "Strategy" msgstr "Стратегия" -#: ml_model/models.py:326 +#: ml_model/models.py:332 msgid "Interaction Type" msgstr "Тип взаимодействия" -#: ml_model/models.py:331 payments/models/invoice.py:19 +#: ml_model/models.py:337 payments/models/invoice.py:19 msgid "Cost" msgstr "Цена" -#: ml_model/models.py:332 +#: ml_model/models.py:338 msgid "In RUB, per specified strategy" msgstr "В рублях, за указанную стратегию" -#: ml_model/models.py:337 +#: ml_model/models.py:343 msgid "Coefficient" msgstr "Коэффициент" -#: ml_model/models.py:338 +#: ml_model/models.py:344 msgid "Cost multiplier" msgstr "Цена" -#: ml_model/models.py:345 +#: ml_model/models.py:351 msgid "Rate" msgstr "Ставка" -#: ml_model/models.py:349 +#: ml_model/models.py:355 msgid "Payment Rule" msgstr "Платежное правило" -#: ml_model/models.py:350 +#: ml_model/models.py:356 msgid "Payment Rules" msgstr "Платежные правила" -#: ml_model/models.py:411 +#: ml_model/models.py:417 msgid "Descriptor" msgstr "Дескриптор" -#: ml_model/models.py:417 +#: ml_model/models.py:423 #, python-format msgid "Instruction of %(model_title)s" msgstr "Инструкция %(model_title)s" -#: ml_model/models.py:420 +#: ml_model/models.py:426 msgid "Model Instruction" msgstr "Инструкция Модели" -#: ml_model/models.py:421 +#: ml_model/models.py:427 msgid "Model Instructions" msgstr "Инструкции Моделей" @@ -1099,24 +1102,29 @@ msgid "no model by this id" msgstr "Не найдено моделей по этому ID" #: ml_model/services/FileService.py:123 -#: tools/public_api/views/providers/openai_compatible.py:208 +#: tools/public_api/views/providers/openai_compatible.py:203 msgid "Voice not found." msgstr "Голос не найден." -#: ml_model/services/FileService.py:227 +#: ml_model/services/FileService.py:271 msgid "Image is too wide or tall" msgstr "Изображение слишком широкое или высокое" +#: ml_model/services/FileService.py:279 +#, python-format +msgid "The attached video must be at most %(max_seconds)d seconds" +msgstr "Прикреплённое видео должно быть не длиннее %(max_seconds)d секунд" + #: ml_model/services/chatgpt.py:245 msgid "Image is ready" msgstr "Изображение готово" -#: ml_model/services/chatgpt.py:361 ml_model/services/claude.py:277 -#: ml_model/services/grok.py:192 +#: ml_model/services/chatgpt.py:358 ml_model/services/claude.py:282 +#: ml_model/services/grok.py:206 msgid "File analysis" msgstr "Анализ файлов" -#: ml_model/services/chatgpt.py:383 ml_model/services/chatgpt_5.py:133 +#: ml_model/services/chatgpt.py:380 ml_model/services/chatgpt_5.py:131 msgid "The \"Use code\" option cannot be used together with an attached image." msgstr "" "Нельзя одновременно использовать параметр «Использовать код» вместе с " @@ -1126,6 +1134,10 @@ msgstr "" msgid "Duration cannot be less than 5 seconds" msgstr "Длительность не может быть меньше 5 секунд" +#: ml_model/services/flux_3.py:77 +msgid "Draft mode is only available at 720p" +msgstr "Режим draft доступен только при 720p" + #: ml_model/services/minio_service.py:37 ml_model/services/minio_service.py:55 #: ml_model/services/minio_service.py:63 ml_model/services/minio_service.py:72 msgid "Unknown bucket destination" @@ -1139,19 +1151,11 @@ msgstr "1080р разрешение не поддерживается для See msgid "3K output is not supported for this model" msgstr "3К разрешение не поддерживается для этой модели" -#: ml_model/services/flux_3.py:87 -msgid "Draft mode is only available at 720p" -msgstr "Режим draft доступен только при 720p" - -#: ml_model/services/FileService.py -msgid "The attached video must be at most %(max_seconds)d seconds" -msgstr "Прикреплённое видео должно быть не длиннее %(max_seconds)d секунд" - #: ml_model/services/upscaleai.py:124 msgid "No image given for improving" msgstr "Нет изображения для улучшения" -#: ml_model/tasks.py:184 +#: ml_model/tasks.py:160 msgid "Lyrics is too long" msgstr "Текст песни слишком длинный" @@ -1159,7 +1163,7 @@ msgstr "Текст песни слишком длинный" msgid "The request must not be empty" msgstr "Запрос не должен быть пустым" -#: ml_model/views.py:65 +#: ml_model/views.py:66 msgid "Model data cannot be retrieved" msgstr "Невозможно получить данные модели" @@ -1185,7 +1189,7 @@ msgstr "UID платёжного метода" msgid "Payments" msgstr "Платежи" -#: payments/exceptions/full_balance.py:5 +#: payments/exceptions/full_balance.py:6 msgid "Your balance is already full" msgstr "Ваш баланс уже пополнен до максимума" @@ -1210,23 +1214,23 @@ msgstr "Активный способ оплаты не найден" msgid "Subscription recovery is already in progress" msgstr "Восстановление подписки уже выполняется" -#: payments/models/attempt.py:12 payments/models/user_payment_method.py:48 +#: payments/models/attempt.py:12 payments/models/user_payment_method.py:50 msgid "Payment Method" msgstr "Платежный метод" -#: payments/models/attempt.py:15 +#: payments/models/attempt.py:17 msgid "Cancel Reason" msgstr "Причина отмены" -#: payments/models/attempt.py:16 +#: payments/models/attempt.py:20 msgid "In Cycle" msgstr "" -#: payments/models/attempt.py:22 +#: payments/models/attempt.py:23 msgid "Payment Attempt" msgstr "Попытка платежа" -#: payments/models/attempt.py:23 +#: payments/models/attempt.py:24 msgid "Payment Attempts" msgstr "Попытки платежа" @@ -1327,19 +1331,19 @@ msgstr "Файл (шт.)" msgid "Time (mins)" msgstr "Время (мин.)" -#: payments/models/payment_plan_feature.py:19 +#: payments/models/payment_plan_feature.py:21 msgid "Quantity" msgstr "Количество" -#: payments/models/payment_plan_feature.py:24 +#: payments/models/payment_plan_feature.py:26 msgid "Measurement unit" msgstr "Единица измерения" -#: payments/models/payment_plan_feature.py:33 +#: payments/models/payment_plan_feature.py:35 msgid "Payment plan feature" msgstr "Преимущество платежного плана" -#: payments/models/payment_plan_feature.py:34 +#: payments/models/payment_plan_feature.py:36 msgid "Payment plan features" msgstr "Преимущества платежного плана" @@ -1411,7 +1415,7 @@ msgstr "СБП" msgid "User Plan Info" msgstr "Информация о плане пользователя" -#: payments/models/user_payment_method.py:25 tools/media/models.py:78 +#: payments/models/user_payment_method.py:25 tools/media/models.py:77 msgid "Meta" msgstr "Метаданные" @@ -1423,7 +1427,7 @@ msgstr "Активен" msgid "Primary" msgstr "" -#: payments/models/user_payment_method.py:49 +#: payments/models/user_payment_method.py:51 msgid "Payment Methods" msgstr "Платежные методы" @@ -1451,13 +1455,13 @@ msgstr "Пополнения" msgid "Messages for this model are not registered in a selector" msgstr "" -#: payments/tests/test_plans.py:23 payments/tests/test_plans.py:205 -#: payments/tests/test_plans.py:208 +#: payments/tests/test_plans.py:23 payments/tests/test_plans.py:206 +#: payments/tests/test_plans.py:209 msgid "Chat-bots" msgstr "Чат-боты" -#: payments/tests/test_plans.py:27 payments/tests/test_plans.py:206 -#: payments/tests/test_plans.py:211 +#: payments/tests/test_plans.py:27 payments/tests/test_plans.py:207 +#: payments/tests/test_plans.py:212 msgid "Images" msgstr "Изображения" @@ -1494,7 +1498,7 @@ msgid "Media" msgstr "Медиа" #: tools/chats/apis.py:219 tools/media/apis.py:246 -#: tools/public_api/views/base.py:108 +#: tools/public_api/views/base.py:150 msgid "" "An unexpected generation error has occurred. Please try again later or use a " "different model" @@ -1515,7 +1519,7 @@ msgstr "Чат %(id)s" msgid "Chat" msgstr "Чат" -#: tools/chats/routes/v1.py:39 tools/public_api/routes/v1.py:68 +#: tools/chats/routes/v1.py:39 tools/public_api/routes/v1.py:69 msgid "Stream not found" msgstr "Стрим не найден" @@ -1523,7 +1527,7 @@ msgstr "Стрим не найден" msgid "Chat not found" msgstr "Чат не найден" -#: tools/chats/routes/v1.py:56 tools/public_api/routes/v1.py:108 +#: tools/chats/routes/v1.py:56 tools/public_api/routes/v1.py:111 msgid "Stream not supported for this model" msgstr "Стриминг не поддерживается для этой модели" @@ -1544,59 +1548,59 @@ msgid "" "Temporary issues with the service, we are already working on a solution." msgstr "Временные неполадки с сервисом, мы уже работаем над их решением." -#: tools/media/models.py:45 +#: tools/media/models.py:44 msgid "Voice clone store" msgstr "Хранилище клонирования голоса" -#: tools/media/models.py:46 +#: tools/media/models.py:45 msgid "Voice clone stores" msgstr "Хранилища клонирования голоса" -#: tools/media/models.py:54 tools/media/models.py:121 +#: tools/media/models.py:53 tools/media/models.py:120 msgid "Voice" msgstr "Голос" -#: tools/media/models.py:55 +#: tools/media/models.py:54 msgid "Instrumental" msgstr "Инструментал" -#: tools/media/models.py:62 +#: tools/media/models.py:61 msgid "Kind" msgstr "Тип" -#: tools/media/models.py:72 tools/media/models.py:105 +#: tools/media/models.py:71 tools/media/models.py:104 msgid "File" msgstr "Файл" -#: tools/media/models.py:84 +#: tools/media/models.py:83 msgid "Preset" msgstr "Пресет" -#: tools/media/models.py:85 +#: tools/media/models.py:84 msgid "Presets" msgstr "Пресеты" -#: tools/media/models.py:93 +#: tools/media/models.py:92 msgid "Создан" msgstr "" -#: tools/media/models.py:94 +#: tools/media/models.py:93 msgid "Изменён" msgstr "" -#: tools/media/models.py:102 +#: tools/media/models.py:101 msgid "Only MP3, OGG, WAV and WEBA audio files are allowed." msgstr "Разрешены только аудиофайлы MP3, OGG, WAV и WEBA." -#: tools/media/models.py:110 +#: tools/media/models.py:109 msgid "Transcription" msgstr "Транскрипция" -#: tools/media/models.py:114 +#: tools/media/models.py:113 msgid "Unknown file" msgstr "Неизвестный файл" -#: tools/media/models.py:122 +#: tools/media/models.py:121 msgid "Voices" msgstr "Голоса" @@ -1633,61 +1637,61 @@ msgstr "Отсутствует обязательный параметр: 'input msgid "Invalid input payload" msgstr "Некорректные данные в поле input" -#: tools/public_api/routes/providers/openai.py:85 -#: tools/public_api/views/providers/elevenlabs_compatible.py:147 -#: tools/public_api/views/providers/openai_compatible.py:110 -#: tools/public_api/views/providers/openai_compatible.py:245 +#: tools/public_api/routes/providers/openai.py:78 +#: tools/public_api/views/providers/elevenlabs_compatible.py:139 +#: tools/public_api/views/providers/openai_compatible.py:103 +#: tools/public_api/views/providers/openai_compatible.py:233 msgid "Model not found" msgstr "Модель не найдена" -#: tools/public_api/routes/providers/openai.py:118 +#: tools/public_api/routes/providers/openai.py:111 msgid "Only streaming is supported" msgstr "Поддерживается только стриминг" -#: tools/public_api/routes/providers/openai.py:120 +#: tools/public_api/routes/providers/openai.py:113 #: tools/public_api/views/providers/openai_compatible.py:61 msgid "You must provide a model parameter" msgstr "Необходимо указать параметр 'model'" -#: tools/public_api/routes/providers/openai.py:136 +#: tools/public_api/routes/providers/openai.py:131 msgid "Only streaming reconnect is supported" msgstr "" -#: tools/public_api/routes/providers/openai.py:138 +#: tools/public_api/routes/providers/openai.py:133 msgid "message_uuid is not provided" msgstr "" -#: tools/public_api/routes/v1.py:33 +#: tools/public_api/routes/v1.py:34 msgid "No API Key in Authorization header" msgstr "" -#: tools/public_api/routes/v1.py:45 +#: tools/public_api/routes/v1.py:46 msgid "API key not found" msgstr "API-ключ не найден" -#: tools/public_api/routes/v1.py:48 +#: tools/public_api/routes/v1.py:49 msgid "API key expired" msgstr "Срок действия API-ключа истёк" -#: tools/public_api/routes/v1.py:50 +#: tools/public_api/routes/v1.py:51 msgid "API key limit exceeded" msgstr "Превышен лимит API-ключа" -#: tools/public_api/routes/v1.py:64 tools/public_api/routes/v1.py:98 +#: tools/public_api/routes/v1.py:65 tools/public_api/routes/v1.py:99 msgid "API key is not available for this account type" msgstr "API-ключ недоступен для этого типа аккаунта" -#: tools/public_api/routes/v1.py:106 tools/public_api/views/base.py:69 +#: tools/public_api/routes/v1.py:109 tools/public_api/views/base.py:92 msgid "Model is blocked by outdating or temporary block, please retry later" msgstr "" "Модель заблокирована, т.к закончила обновляться или временно заблокирована, " "попробуйте позже" -#: tools/public_api/views/base.py:64 +#: tools/public_api/views/base.py:84 msgid "Key limit exceeded" msgstr "Превышен лимит по ключу" -#: tools/public_api/views/providers/elevenlabs_compatible.py:133 +#: tools/public_api/views/providers/elevenlabs_compatible.py:132 msgid "Missing required parameter: model_id" msgstr "Отсутствует обязательный параметр: 'model_id'" @@ -1695,24 +1699,24 @@ msgstr "Отсутствует обязательный параметр: 'model msgid "Missing required parameter: 'messages'" msgstr "Отсутствует обязательный параметр: 'messages'" -#: tools/public_api/views/providers/openai_compatible.py:176 +#: tools/public_api/views/providers/openai_compatible.py:170 msgid "Missing audio_sample." msgstr "Отсутствует параметр audio_sample." -#: tools/public_api/views/providers/openai_compatible.py:231 +#: tools/public_api/views/providers/openai_compatible.py:226 #, python-format msgid "Missing required parameter: %(param)s" msgstr "Отсутствует обязательный параметр: %(param)s" -#: tools/public_api/views/providers/openai_compatible.py:249 +#: tools/public_api/views/providers/openai_compatible.py:237 msgid "Voice must be an object with id." msgstr "Поле voice должно быть объектом с полем id." -#: tools/public_api/views/providers/openai_compatible.py:255 +#: tools/public_api/views/providers/openai_compatible.py:243 msgid "Voice id is empty." msgstr "Идентификатор голоса не указан." -#: tools/public_api/views/providers/openai_compatible.py:286 +#: tools/public_api/views/providers/openai_compatible.py:276 msgid "Failed to fetch generated audio" msgstr "Не удалось получить сгенерированное аудио" @@ -14,6 +14,7 @@ from ml_model.exceptions import ( GenerationException, InputImageSensitiveContentError, OutputSensitiveImageContentError, + OutputSensitiveVideoContentError, RealPersonDetectedError, RequestBlocked, PromptLengthExceeded, @@ -140,21 +141,29 @@ class BytedanceModelArkAdapter: def _raise_by_error_payload(cls, data: dict[str, Any], choices: list[dict[str, Any]]) -> None: choice_reasons = {str(choice.get('finish_reason', '')).lower() for choice in choices} - if cls._is_request_blocked_error(data): - raise RequestBlocked + cls._raise_for_error(data) if BytedanceFinishReason.CONTENT_FILTER in choice_reasons: raise RequestBlocked raise GenerationException - @staticmethod - def _is_request_blocked_error(data: dict[str, Any]) -> bool: + @classmethod + def _raise_for_error(cls, data: dict[str, Any]) -> None: error = data.get('error') if not isinstance(error, dict): - return False - - return str(error.get('code', '')) == 'InputTextSensitiveContentDetected' + return + error_code = str(error.get('code', '')) + if error_code.startswith('OutputImageSensitiveContentDetected'): + raise OutputSensitiveImageContentError + if error_code.startswith('OutputVideoSensitiveContentDetected'): + raise OutputSensitiveVideoContentError + if error_code == 'InputImageSensitiveContentDetected': + raise InputImageSensitiveContentError + if error_code == 'InputImageSensitiveContentDetected.PrivacyInformation': + raise RealPersonDetectedError + if error_code == 'InputTextSensitiveContentDetected': + raise RequestBlocked @classmethod def _extract_chat_answer( @@ -372,20 +381,13 @@ class BytedanceModelArkAdapter: resp.text, ) raise GenerationException from exc - if error_code := data.get('error', {}).get('code', ''): - if error_code == 'OutputImageSensitiveContentDetected': - raise OutputSensitiveImageContentError - if error_code == 'InputImageSensitiveContentDetected': - raise InputImageSensitiveContentError - + cls._raise_for_error(data) if image_data := data.get('data'): urls = [ item.get('url') for item in image_data if isinstance(item, dict) and item.get('url') ] if urls: return urls - if cls._is_request_blocked_error(data): - raise RequestBlocked logger.error( 'Bytedance images/generations status=%s response=%s', resp.status_code, @@ -421,16 +423,7 @@ class BytedanceModelArkAdapter: raise GenerationException from exc if data.get('id') or data.get('task_id'): return data - if error_code := data.get('error', {}).get('code', None): - match error_code: - case 'InputImageSensitiveContentDetected': - raise InputImageSensitiveContentError - case 'InputImageSensitiveContentDetected.PrivacyInformation': - raise RealPersonDetectedError - case _: - raise GenerationException - if cls._is_request_blocked_error(data): - raise RequestBlocked + cls._raise_for_error(data) logger.error( 'Bytedance contents/generations/tasks create status=%s response=%s', resp.status_code, @@ -465,8 +458,7 @@ class BytedanceModelArkAdapter: raise GenerationException from exc if data.get('id') or data.get('task_id'): return data - if cls._is_request_blocked_error(data): - raise RequestBlocked + cls._raise_for_error(data) logger.error( 'Bytedance contents/generations/tasks retrieve status=%s task_id=%s response=%s', resp.status_code, @@ -477,10 +469,9 @@ class BytedanceModelArkAdapter: @classmethod def _wait_video_task_result(cls, task_id: str) -> RunVideoResult: - for _ in range(cls.VIDEO_POLL_ATTEMPTS_LIMIT): + for _attempt in range(cls.VIDEO_POLL_ATTEMPTS_LIMIT): data = cls._retrieve_video_task(task_id=task_id) - if cls._is_request_blocked_error(data): - raise RequestBlocked + cls._raise_for_error(data) status = str(data.get('status', '')).lower() if status == BytedanceVideoTaskStatus.SUCCEEDED: return data['content']['video_url'], data['usage']['completion_tokens'] @@ -204,9 +204,21 @@ class RealPersonDetectedError(Exception): return _('The input image may contain real person.') -class OutputSensitiveImageContentError(Exception): +class OutputSensitiveContentError(Exception): + CONTENT_TYPE = 'content' + def __str__(self) -> str: - return _('The generated image may contain private or prohibited content') + return _('The generated %(content_type)s may contain private or prohibited content') % { + 'content_type': _(self.CONTENT_TYPE), + } + + +class OutputSensitiveImageContentError(OutputSensitiveContentError): + CONTENT_TYPE = 'image' + + +class OutputSensitiveVideoContentError(OutputSensitiveContentError): + CONTENT_TYPE = 'video' class InputImageSensitiveContentError(Exception): @@ -31,7 +31,7 @@ from ml_model.exceptions import ( InputImageSensitiveContentError, InvalidParameterError, ModelVersionNotAvailable, - OutputSensitiveImageContentError, + OutputSensitiveContentError, PaidPlanRequiredError, PromptLengthExceeded, RequestBlocked, @@ -198,7 +198,7 @@ class MessagesAPIView(APIView): InvalidParameterError, ModelVersionNotAvailable, InputImageSensitiveContentError, - OutputSensitiveImageContentError, + OutputSensitiveContentError, ImageTooLargeError, ) as exc: return Response({'detail': str(exc)}, status=HTTP_400_BAD_REQUEST) @@ -28,7 +28,7 @@ from ml_model.exceptions import ( InvalidStyleCombinationError, ModelCouldNotInterpretPrompt, ModelVersionNotAvailable, - OutputSensitiveImageContentError, + OutputSensitiveContentError, PromptLengthExceeded, RealPersonDetectedError, RequestBlocked, @@ -221,7 +221,7 @@ class MediaAPIView(APIView): FaceNotFoundError, RealPersonDetectedError, InputImageSensitiveContentError, - OutputSensitiveImageContentError, + OutputSensitiveContentError, ImageTooLargeError, ) as exc: return Response({'detail': str(exc)}, status=HTTP_400_BAD_REQUEST) @@ -28,7 +28,7 @@ from ml_model.exceptions import ( InvalidParameterError, ModelVersionNotAvailable, NeuronModelNotExist, - OutputSensitiveImageContentError, + OutputSensitiveContentError, PaidPlanRequiredError, PromptLengthExceeded, RequestBlocked, @@ -133,7 +133,7 @@ class BaseGenerationView(APIView): InvalidParameterError, ModelVersionNotAvailable, InputImageSensitiveContentError, - OutputSensitiveImageContentError, + OutputSensitiveContentError, ImageTooLargeError, ValidationError, ) as exc: