From 3d4dae51ea011c972f17a78752a35b5b0f8463cd Mon Sep 17 00:00:00 2001 From: Milos Marinkovic Date: Fri, 31 Jul 2026 19:56:56 +0200 Subject: [PATCH 1/2] Add video generation features --- src/assets/i18n/ar.json | 21 +++++++++++--- src/assets/i18n/de.json | 21 +++++++++++--- src/assets/i18n/en.json | 21 +++++++++++--- src/assets/i18n/es.json | 21 +++++++++++--- src/assets/i18n/fr.json | 21 +++++++++++--- src/assets/i18n/hi.json | 21 +++++++++++--- src/assets/i18n/it.json | 21 +++++++++++--- src/assets/i18n/ru.json | 21 +++++++++++--- src/assets/i18n/sr.json | 21 +++++++++++--- src/assets/i18n/tr.json | 21 +++++++++++--- src/assets/i18n/zh.json | 21 +++++++++++--- src/components/AdvancedToolsPanel.tsx | 4 +++ src/components/CostEstimateDialog.tsx | 38 ++++++++++++++++++++++++++ src/components/UsageRecordCard.tsx | 23 ++++++++++++++++ src/lib/api-error.ts | 3 ++ src/lib/translation-keys.ts | 11 ++++++++ src/services/external-tools-service.ts | 4 +++ src/services/usage-service.ts | 2 ++ src/services/user-settings-service.ts | 3 ++ 19 files changed, 275 insertions(+), 44 deletions(-) diff --git a/src/assets/i18n/ar.json b/src/assets/i18n/ar.json index b938d2fa..276b4950 100644 --- a/src/assets/i18n/ar.json +++ b/src/assets/i18n/ar.json @@ -145,7 +145,9 @@ "input_image_sizes": "صور الإدخال", "status_label": "الحالة", "status_completed": "مكتمل", - "status_failed": "فشل" + "status_failed": "فشل", + "output_video_size": "فيديو الإخراج", + "output_video_duration": "مدة الفيديو" }, "transfer": { "to": "إلى", @@ -316,7 +318,7 @@ "title": "تحليل المحتوى" }, "image_tools": { - "title": "أدوات الصور" + "title": "أدوات الصور والفيديو" }, "integrations": { "title": "التكاملات" @@ -382,6 +384,10 @@ "deprecated": { "title": "مُهمل", "description": "هذه الأداة أو الميزة مُهملة وقد تُزال في الإصدارات المستقبلية." + }, + "videos_gen": { + "title": "توليد الفيديو", + "description": "هذا نموذج يُستخدم لتوليد الفيديوهات من المطالبات والصور المرجعية." } } }, @@ -510,7 +516,10 @@ "invalid_stock_symbol": "رمز السهم غير صالح", "stock_quote_not_found": "لم يتم العثور على سعر السهم", "stock_quote_failed": "فشل جلب سعر السهم", - "stock_quote_rate_limited": "تم تجاوز حد طلبات أسعار الأسهم" + "stock_quote_rate_limited": "تم تجاوز حد طلبات أسعار الأسهم", + "video_preparation_failed": "فشل تحضير الفيديو", + "video_generation_failed": "فشل توليد الفيديو", + "video_runtime_missing": "بيئة تشغيل الفيديو المطلوبة غير متاحة" }, "features": { "header": "الميزات", @@ -598,7 +607,11 @@ "api_call": "لكل استخدام واحد", "second_of_runtime": "لكل ثانية تشغيل", "web_search_query": "لكل استعلام بحث ويب", - "max_input_images": "حتى {maxImages} صور مرجعية" + "max_input_images": "حتى {maxImages} صور مرجعية", + "output_video_costs": "تكاليف فيديو الإخراج", + "output_video_1k_second": "1K/ث", + "output_video_2k_second": "2K/ث", + "output_video_4k_second": "4K/ث" }, "onboarding": { "page_title": "ابدأ الآن", diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index 82781a93..58d1b69e 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -145,7 +145,9 @@ "input_image_sizes": "Eingabebilder", "status_label": "Status", "status_completed": "Abgeschlossen", - "status_failed": "Fehlgeschlagen" + "status_failed": "Fehlgeschlagen", + "output_video_size": "Ausgabevideo", + "output_video_duration": "Videodauer" }, "transfer": { "to": "An", @@ -316,7 +318,7 @@ "title": "Inhaltsanalyse" }, "image_tools": { - "title": "Bildtools" + "title": "Bild- und Video-Tools" }, "integrations": { "title": "Integrationen" @@ -382,6 +384,10 @@ "deprecated": { "title": "Veraltet", "description": "Dieses Tool oder diese Funktion ist veraltet und kann in zukünftigen Versionen entfernt werden." + }, + "videos_gen": { + "title": "Videogenerierung", + "description": "Dies ist ein Modell, das Videos aus Prompts und Referenzbildern generiert." } } }, @@ -510,7 +516,10 @@ "invalid_stock_symbol": "Ungültiges Aktiensymbol", "stock_quote_not_found": "Aktienkurs nicht gefunden", "stock_quote_failed": "Aktienkurs konnte nicht abgerufen werden", - "stock_quote_rate_limited": "Anfragelimit für Aktienkurse erreicht" + "stock_quote_rate_limited": "Anfragelimit für Aktienkurse erreicht", + "video_preparation_failed": "Vorbereitung des Videos fehlgeschlagen", + "video_generation_failed": "Videogenerierung fehlgeschlagen", + "video_runtime_missing": "Erforderliche Video-Laufzeitumgebung ist nicht verfügbar" }, "features": { "header": "Funktionen", @@ -598,7 +607,11 @@ "api_call": "Pro einzelne Verwendung", "second_of_runtime": "Pro Sekunde Laufzeit", "web_search_query": "Pro Web-Suchanfrage", - "max_input_images": "Bis zu {maxImages} Referenzbilder" + "max_input_images": "Bis zu {maxImages} Referenzbilder", + "output_video_costs": "Kosten für Ausgabevideos", + "output_video_1k_second": "1K/s", + "output_video_2k_second": "2K/s", + "output_video_4k_second": "4K/s" }, "onboarding": { "page_title": "Loslegen", diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 64e37887..662a063f 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -145,7 +145,9 @@ "input_image_sizes": "Input Images", "status_label": "Status", "status_completed": "Completed", - "status_failed": "Failed" + "status_failed": "Failed", + "output_video_size": "Output Video", + "output_video_duration": "Video Duration" }, "transfer": { "to": "To", @@ -316,7 +318,7 @@ "title": "Content Analysis" }, "image_tools": { - "title": "Image Tools" + "title": "Image & Video Tools" }, "integrations": { "title": "Integrations" @@ -382,6 +384,10 @@ "deprecated": { "title": "Deprecated", "description": "This tool or feature is deprecated and may be removed in future versions." + }, + "videos_gen": { + "title": "Video Generation", + "description": "This is a model that is used for generating videos from prompts and reference images." } } }, @@ -510,7 +516,10 @@ "invalid_stock_symbol": "Invalid stock symbol", "stock_quote_not_found": "Stock quote not found", "stock_quote_failed": "Failed to retrieve stock quote", - "stock_quote_rate_limited": "Stock quote request limit reached" + "stock_quote_rate_limited": "Stock quote request limit reached", + "video_preparation_failed": "Failed to prepare the video", + "video_generation_failed": "Failed to generate the video", + "video_runtime_missing": "Required video runtime is not available" }, "features": { "header": "Features", @@ -598,7 +607,11 @@ "api_call": "Per single use", "second_of_runtime": "Per second of runtime", "web_search_query": "Per web search query", - "max_input_images": "Up to {maxImages} reference images" + "max_input_images": "Up to {maxImages} reference images", + "output_video_costs": "Output Video Costs", + "output_video_1k_second": "1K/s", + "output_video_2k_second": "2K/s", + "output_video_4k_second": "4K/s" }, "onboarding": { "page_title": "Get Started", diff --git a/src/assets/i18n/es.json b/src/assets/i18n/es.json index bde79194..123eda36 100644 --- a/src/assets/i18n/es.json +++ b/src/assets/i18n/es.json @@ -145,7 +145,9 @@ "input_image_sizes": "Imágenes de entrada", "status_label": "Estado", "status_completed": "Completado", - "status_failed": "Fallido" + "status_failed": "Fallido", + "output_video_size": "Video de salida", + "output_video_duration": "Duración del video" }, "transfer": { "to": "A", @@ -316,7 +318,7 @@ "title": "Análisis de Contenido" }, "image_tools": { - "title": "Herramientas de Imagen" + "title": "Herramientas de imagen y video" }, "integrations": { "title": "Integraciones" @@ -382,6 +384,10 @@ "deprecated": { "title": "Obsoleto", "description": "Esta herramienta o función está obsoleta y puede ser eliminada en versiones futuras." + }, + "videos_gen": { + "title": "Generación de video", + "description": "Este es un modelo que se usa para generar videos a partir de indicaciones e imágenes de referencia." } } }, @@ -510,7 +516,10 @@ "invalid_stock_symbol": "Símbolo bursátil no válido", "stock_quote_not_found": "Cotización bursátil no encontrada", "stock_quote_failed": "No se pudo obtener la cotización bursátil", - "stock_quote_rate_limited": "Se alcanzó el límite de solicitudes de cotizaciones bursátiles" + "stock_quote_rate_limited": "Se alcanzó el límite de solicitudes de cotizaciones bursátiles", + "video_preparation_failed": "Error al preparar el video", + "video_generation_failed": "Error al generar el video", + "video_runtime_missing": "El entorno de video requerido no está disponible" }, "features": { "header": "Funciones", @@ -598,7 +607,11 @@ "api_call": "Por uso único", "second_of_runtime": "Por segundo de ejecución", "web_search_query": "Por consulta de búsqueda web", - "max_input_images": "Hasta {maxImages} imágenes de referencia" + "max_input_images": "Hasta {maxImages} imágenes de referencia", + "output_video_costs": "Costos de video de salida", + "output_video_1k_second": "1K/s", + "output_video_2k_second": "2K/s", + "output_video_4k_second": "4K/s" }, "onboarding": { "page_title": "Comenzar", diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index 7af60972..a83f3a45 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -145,7 +145,9 @@ "input_image_sizes": "Images d'entrée", "status_label": "Statut", "status_completed": "Terminé", - "status_failed": "Échoué" + "status_failed": "Échoué", + "output_video_size": "Vidéo de sortie", + "output_video_duration": "Durée de la vidéo" }, "transfer": { "to": "À", @@ -316,7 +318,7 @@ "title": "Analyse de Contenu" }, "image_tools": { - "title": "Outils d'Image" + "title": "Outils image et vidéo" }, "integrations": { "title": "Intégrations" @@ -382,6 +384,10 @@ "deprecated": { "title": "Obsolète", "description": "Cet outil ou cette fonctionnalité est obsolète et pourrait être supprimé dans les versions futures." + }, + "videos_gen": { + "title": "Génération de vidéos", + "description": "C'est un modèle utilisé pour générer des vidéos à partir d'invites et d'images de référence." } } }, @@ -510,7 +516,10 @@ "invalid_stock_symbol": "Symbole boursier invalide", "stock_quote_not_found": "Cours de l'action introuvable", "stock_quote_failed": "Impossible de récupérer le cours de l'action", - "stock_quote_rate_limited": "Limite de demandes de cours d'actions atteinte" + "stock_quote_rate_limited": "Limite de demandes de cours d'actions atteinte", + "video_preparation_failed": "Échec de la préparation de la vidéo", + "video_generation_failed": "Échec de la génération de la vidéo", + "video_runtime_missing": "L'environnement vidéo requis n'est pas disponible" }, "features": { "header": "Fonctionnalités", @@ -598,7 +607,11 @@ "api_call": "Par utilisation unique", "second_of_runtime": "Par seconde d'exécution", "web_search_query": "Par requête de recherche web", - "max_input_images": "Jusqu'à {maxImages} images de référence" + "max_input_images": "Jusqu'à {maxImages} images de référence", + "output_video_costs": "Coûts des vidéos de sortie", + "output_video_1k_second": "1K/s", + "output_video_2k_second": "2K/s", + "output_video_4k_second": "4K/s" }, "onboarding": { "page_title": "Commencer", diff --git a/src/assets/i18n/hi.json b/src/assets/i18n/hi.json index 9e327c2c..3bd562c0 100644 --- a/src/assets/i18n/hi.json +++ b/src/assets/i18n/hi.json @@ -145,7 +145,9 @@ "input_image_sizes": "इनपुट छवियाँ", "status_label": "स्थिति", "status_completed": "पूर्ण", - "status_failed": "विफल" + "status_failed": "विफल", + "output_video_size": "आउटपुट वीडियो", + "output_video_duration": "वीडियो अवधि" }, "transfer": { "to": "को", @@ -316,7 +318,7 @@ "title": "सामग्री विश्लेषण" }, "image_tools": { - "title": "छवि उपकरण" + "title": "छवि और वीडियो टूल" }, "integrations": { "title": "एकीकरण" @@ -382,6 +384,10 @@ "deprecated": { "title": "अप्रचलित", "description": "यह टूल या सुविधा अप्रचलित है और भविष्य के संस्करणों में हटाया जा सकता है।" + }, + "videos_gen": { + "title": "वीडियो उत्पादन", + "description": "यह मॉडल संकेतों और संदर्भ छवियों से वीडियो बनाने के लिए उपयोग किया जाता है।" } } }, @@ -510,7 +516,10 @@ "invalid_stock_symbol": "अमान्य शेयर प्रतीक", "stock_quote_not_found": "शेयर भाव नहीं मिला", "stock_quote_failed": "शेयर भाव प्राप्त करने में विफल", - "stock_quote_rate_limited": "शेयर भाव अनुरोध सीमा पूरी हो गई" + "stock_quote_rate_limited": "शेयर भाव अनुरोध सीमा पूरी हो गई", + "video_preparation_failed": "वीडियो तैयार करने में विफल", + "video_generation_failed": "वीडियो बनाने में विफल", + "video_runtime_missing": "आवश्यक वीडियो रनटाइम उपलब्ध नहीं है" }, "features": { "header": "विशेषताएं", @@ -598,7 +607,11 @@ "api_call": "प्रति एकल उपयोग", "second_of_runtime": "प्रति सेकंड रनटाइम", "web_search_query": "प्रति वेब खोज क्वेरी", - "max_input_images": "अधिकतम {maxImages} संदर्भ चित्र" + "max_input_images": "अधिकतम {maxImages} संदर्भ चित्र", + "output_video_costs": "आउटपुट वीडियो लागत", + "output_video_1k_second": "1K/सेकंड", + "output_video_2k_second": "2K/सेकंड", + "output_video_4k_second": "4K/सेकंड" }, "onboarding": { "page_title": "शुरू करें", diff --git a/src/assets/i18n/it.json b/src/assets/i18n/it.json index 9cc3e0de..30456533 100644 --- a/src/assets/i18n/it.json +++ b/src/assets/i18n/it.json @@ -145,7 +145,9 @@ "input_image_sizes": "Immagini di input", "status_label": "Stato", "status_completed": "Completato", - "status_failed": "Fallito" + "status_failed": "Fallito", + "output_video_size": "Video di output", + "output_video_duration": "Durata video" }, "transfer": { "to": "A", @@ -316,7 +318,7 @@ "title": "Analisi del Contenuto" }, "image_tools": { - "title": "Strumenti Immagine" + "title": "Strumenti immagine e video" }, "integrations": { "title": "Integrazioni" @@ -382,6 +384,10 @@ "deprecated": { "title": "Obsoleto", "description": "Questo strumento o funzionalità è obsoleto e potrebbe essere rimosso nelle versioni future." + }, + "videos_gen": { + "title": "Generazione video", + "description": "Questo è un modello usato per generare video da prompt e immagini di riferimento." } } }, @@ -510,7 +516,10 @@ "invalid_stock_symbol": "Simbolo azionario non valido", "stock_quote_not_found": "Quotazione azionaria non trovata", "stock_quote_failed": "Impossibile recuperare la quotazione azionaria", - "stock_quote_rate_limited": "Limite di richieste di quotazioni azionarie raggiunto" + "stock_quote_rate_limited": "Limite di richieste di quotazioni azionarie raggiunto", + "video_preparation_failed": "Preparazione del video non riuscita", + "video_generation_failed": "Generazione del video non riuscita", + "video_runtime_missing": "Runtime video richiesto non disponibile" }, "features": { "header": "Funzionalità", @@ -598,7 +607,11 @@ "api_call": "Per singolo uso", "second_of_runtime": "Per secondo di esecuzione", "web_search_query": "Per query di ricerca web", - "max_input_images": "Fino a {maxImages} immagini di riferimento" + "max_input_images": "Fino a {maxImages} immagini di riferimento", + "output_video_costs": "Costi video di output", + "output_video_1k_second": "1K/s", + "output_video_2k_second": "2K/s", + "output_video_4k_second": "4K/s" }, "onboarding": { "page_title": "Inizia", diff --git a/src/assets/i18n/ru.json b/src/assets/i18n/ru.json index 77bfdfd0..67511a0a 100644 --- a/src/assets/i18n/ru.json +++ b/src/assets/i18n/ru.json @@ -145,7 +145,9 @@ "input_image_sizes": "Входные изображения", "status_label": "Статус", "status_completed": "Выполнено", - "status_failed": "Ошибка" + "status_failed": "Ошибка", + "output_video_size": "Выходное видео", + "output_video_duration": "Длительность видео" }, "transfer": { "to": "Кому", @@ -316,7 +318,7 @@ "title": "Анализ Контента" }, "image_tools": { - "title": "Инструменты Изображений" + "title": "Инструменты изображений и видео" }, "integrations": { "title": "Интеграции" @@ -382,6 +384,10 @@ "deprecated": { "title": "Устаревший", "description": "Этот инструмент или функция устарели и могут быть удалены в будущих версиях." + }, + "videos_gen": { + "title": "Генерация видео", + "description": "Это модель, которая используется для генерации видео по подсказкам и референсным изображениям." } } }, @@ -510,7 +516,10 @@ "invalid_stock_symbol": "Недопустимый биржевой символ", "stock_quote_not_found": "Котировка акции не найдена", "stock_quote_failed": "Не удалось получить котировку акции", - "stock_quote_rate_limited": "Достигнут лимит запросов котировок акций" + "stock_quote_rate_limited": "Достигнут лимит запросов котировок акций", + "video_preparation_failed": "Не удалось подготовить видео", + "video_generation_failed": "Не удалось сгенерировать видео", + "video_runtime_missing": "Необходимая видеосреда выполнения недоступна" }, "features": { "header": "Возможности", @@ -598,7 +607,11 @@ "api_call": "За одно использование", "second_of_runtime": "За секунду работы", "web_search_query": "За поисковый запрос в интернете", - "max_input_images": "До {maxImages} справочных изображений" + "max_input_images": "До {maxImages} справочных изображений", + "output_video_costs": "Стоимость выходного видео", + "output_video_1k_second": "1K/с", + "output_video_2k_second": "2K/с", + "output_video_4k_second": "4K/с" }, "onboarding": { "page_title": "Начать", diff --git a/src/assets/i18n/sr.json b/src/assets/i18n/sr.json index 7f5b993b..91905619 100644 --- a/src/assets/i18n/sr.json +++ b/src/assets/i18n/sr.json @@ -145,7 +145,9 @@ "input_image_sizes": "Ulazne slike", "status_label": "Status", "status_completed": "Uspešno", - "status_failed": "Neuspešno" + "status_failed": "Neuspešno", + "output_video_size": "Izlazni video", + "output_video_duration": "Trajanje videa" }, "transfer": { "to": "Za", @@ -316,7 +318,7 @@ "title": "Analiza sadržaja" }, "image_tools": { - "title": "Alati za slike" + "title": "Alati za slike i video" }, "integrations": { "title": "Integracije" @@ -382,6 +384,10 @@ "deprecated": { "title": "Zastarelo", "description": "Ovaj alat ili funkcija je zastarela i može biti uklonjena u budućim verzijama." + }, + "videos_gen": { + "title": "Generisanje videa", + "description": "Ovo je model koji se koristi za generisanje videa iz upita i referentnih slika." } } }, @@ -510,7 +516,10 @@ "invalid_stock_symbol": "Nevažeći simbol akcije", "stock_quote_not_found": "Berzanska kotacija nije pronađena", "stock_quote_failed": "Preuzimanje berzanske kotacije nije uspelo", - "stock_quote_rate_limited": "Dostignuto je ograničenje zahteva za berzanske kotacije" + "stock_quote_rate_limited": "Dostignuto je ograničenje zahteva za berzanske kotacije", + "video_preparation_failed": "Priprema videa nije uspela", + "video_generation_failed": "Generisanje videa nije uspelo", + "video_runtime_missing": "Potreban video runtime nije dostupan" }, "features": { "header": "Mogućnosti", @@ -598,7 +607,11 @@ "api_call": "Po jednoj upotrebi", "second_of_runtime": "Po sekundi izvršavanja", "web_search_query": "Po upitu za internet pretragu", - "max_input_images": "Do {maxImages} referentnih slika" + "max_input_images": "Do {maxImages} referentnih slika", + "output_video_costs": "Troškovi izlaznog videa", + "output_video_1k_second": "1K/s", + "output_video_2k_second": "2K/s", + "output_video_4k_second": "4K/s" }, "onboarding": { "page_title": "Početak", diff --git a/src/assets/i18n/tr.json b/src/assets/i18n/tr.json index 62eedf42..a08e469e 100644 --- a/src/assets/i18n/tr.json +++ b/src/assets/i18n/tr.json @@ -145,7 +145,9 @@ "input_image_sizes": "Giriş Görselleri", "status_label": "Durum", "status_completed": "Tamamlandı", - "status_failed": "Başarısız" + "status_failed": "Başarısız", + "output_video_size": "Çıktı videosu", + "output_video_duration": "Video süresi" }, "transfer": { "to": "Kime", @@ -316,7 +318,7 @@ "title": "İçerik Analizi" }, "image_tools": { - "title": "Görüntü Araçları" + "title": "Görüntü ve Video Araçları" }, "integrations": { "title": "Entegrasyonlar" @@ -382,6 +384,10 @@ "deprecated": { "title": "Kullanımdan Kaldırıldı", "description": "Bu araç veya özellik kullanımdan kaldırıldı ve gelecek sürümlerde kaldırılabilir." + }, + "videos_gen": { + "title": "Video Üretimi", + "description": "Bu, istemlerden ve referans görüntülerden video üretmek için kullanılan bir modeldir." } } }, @@ -510,7 +516,10 @@ "invalid_stock_symbol": "Geçersiz hisse senedi sembolü", "stock_quote_not_found": "Hisse senedi fiyatı bulunamadı", "stock_quote_failed": "Hisse senedi fiyatı alınamadı", - "stock_quote_rate_limited": "Hisse senedi fiyatı istek sınırına ulaşıldı" + "stock_quote_rate_limited": "Hisse senedi fiyatı istek sınırına ulaşıldı", + "video_preparation_failed": "Video hazırlama başarısız oldu", + "video_generation_failed": "Video üretimi başarısız oldu", + "video_runtime_missing": "Gerekli video çalışma zamanı mevcut değil" }, "features": { "header": "Özellikler", @@ -598,7 +607,11 @@ "api_call": "Tek kullanım başına", "second_of_runtime": "Çalışma süresi saniyesi başına", "web_search_query": "Web arama sorgusu başına", - "max_input_images": "{maxImages} adede kadar referans görsel" + "max_input_images": "{maxImages} adede kadar referans görsel", + "output_video_costs": "Çıktı video maliyetleri", + "output_video_1k_second": "1K/sn", + "output_video_2k_second": "2K/sn", + "output_video_4k_second": "4K/sn" }, "onboarding": { "page_title": "Başlayın", diff --git a/src/assets/i18n/zh.json b/src/assets/i18n/zh.json index 5f23e506..c45c69ae 100644 --- a/src/assets/i18n/zh.json +++ b/src/assets/i18n/zh.json @@ -145,7 +145,9 @@ "input_image_sizes": "输入图像", "status_label": "状态", "status_completed": "已完成", - "status_failed": "失败" + "status_failed": "失败", + "output_video_size": "输出视频", + "output_video_duration": "视频时长" }, "transfer": { "to": "发送至", @@ -316,7 +318,7 @@ "title": "内容分析" }, "image_tools": { - "title": "图像工具" + "title": "图像和视频工具" }, "integrations": { "title": "集成" @@ -382,6 +384,10 @@ "deprecated": { "title": "已弃用", "description": "此工具或功能已弃用,可能会在未来版本中移除。" + }, + "videos_gen": { + "title": "视频生成", + "description": "这是用于根据提示和参考图像生成视频的模型。" } } }, @@ -510,7 +516,10 @@ "invalid_stock_symbol": "无效的股票代码", "stock_quote_not_found": "未找到股票报价", "stock_quote_failed": "获取股票报价失败", - "stock_quote_rate_limited": "已达到股票报价请求限制" + "stock_quote_rate_limited": "已达到股票报价请求限制", + "video_preparation_failed": "视频准备失败", + "video_generation_failed": "视频生成失败", + "video_runtime_missing": "所需的视频运行环境不可用" }, "features": { "header": "功能", @@ -598,7 +607,11 @@ "api_call": "每次使用", "second_of_runtime": "每秒运行时间", "web_search_query": "每次网页搜索查询", - "max_input_images": "最多 {maxImages} 张参考图片" + "max_input_images": "最多 {maxImages} 张参考图片", + "output_video_costs": "输出视频费用", + "output_video_1k_second": "1K/秒", + "output_video_2k_second": "2K/秒", + "output_video_4k_second": "4K/秒" }, "onboarding": { "page_title": "开始使用", diff --git a/src/components/AdvancedToolsPanel.tsx b/src/components/AdvancedToolsPanel.tsx index dbe3214d..e80baa9e 100644 --- a/src/components/AdvancedToolsPanel.tsx +++ b/src/components/AdvancedToolsPanel.tsx @@ -7,6 +7,7 @@ import { Ear, WandSparkles, ImageUp, + Clapperboard, Binoculars, DatabaseZap, Euro, @@ -87,6 +88,7 @@ const getToolGroupCategory = (toolType: ToolType): ToolGroupCategory => { embedding: "content_analysis", images_gen: "image_tools", images_edit: "image_tools", + videos_gen: "image_tools", search: "integrations", api_fiat_exchange: "integrations", api_crypto_exchange: "integrations", @@ -181,6 +183,7 @@ const AdvancedToolsPanel: React.FC = ({ embedding: "content_analysis", images_gen: "image_tools", images_edit: "image_tools", + videos_gen: "image_tools", search: "integrations", api_fiat_exchange: "integrations", api_crypto_exchange: "integrations", @@ -208,6 +211,7 @@ const AdvancedToolsPanel: React.FC = ({ hearing: Ear, images_gen: WandSparkles, images_edit: ImageUp, + videos_gen: Clapperboard, search: Binoculars, embedding: DatabaseZap, api_fiat_exchange: Euro, diff --git a/src/components/CostEstimateDialog.tsx b/src/components/CostEstimateDialog.tsx index b62dfd58..1ff52b8b 100644 --- a/src/components/CostEstimateDialog.tsx +++ b/src/components/CostEstimateDialog.tsx @@ -104,6 +104,24 @@ const CostEstimateContent: React.FC<{ }, ].filter((item) => item.value != null); + const outputVideoCosts = [ + { + key: "output_video_1k_second", + label: t("cost_estimate.output_video_1k_second"), + value: costEstimate.output_video_1k_second, + }, + { + key: "output_video_2k_second", + label: t("cost_estimate.output_video_2k_second"), + value: costEstimate.output_video_2k_second, + }, + { + key: "output_video_4k_second", + label: t("cost_estimate.output_video_4k_second"), + value: costEstimate.output_video_4k_second, + }, + ].filter((item) => item.value != null); + const otherCosts = [ { key: "api_call", @@ -126,6 +144,7 @@ const CostEstimateContent: React.FC<{ tokenCosts.length > 0 || inputImageCosts.length > 0 || outputImageCosts.length > 0 || + outputVideoCosts.length > 0 || otherCosts.length > 0; return ( @@ -212,6 +231,25 @@ const CostEstimateContent: React.FC<{ )} + {outputVideoCosts.length > 0 && ( +
+

+ {t("cost_estimate.output_video_costs")} +

+
+ {outputVideoCosts.map((item) => ( +
+ {item.label} + {formatCost(item.value!)} +
+ ))} +
+
+ )} + {otherCosts.length > 0 && (

diff --git a/src/components/UsageRecordCard.tsx b/src/components/UsageRecordCard.tsx index a8c0a103..c4efccfd 100644 --- a/src/components/UsageRecordCard.tsx +++ b/src/components/UsageRecordCard.tsx @@ -499,6 +499,29 @@ const UsageRecordCard: React.FC = ({

)} + {record.output_video_size && ( +
+ + {t("usage.context_ids.output_video_size")} + + + {record.output_video_size.toUpperCase()} + +
+ )} + {record.output_video_duration_seconds != null && ( +
+ + {t("usage.context_ids.output_video_duration")} + + + {formatRuntime(record.output_video_duration_seconds)} + +
+ )} diff --git a/src/lib/api-error.ts b/src/lib/api-error.ts index 1b9c265b..432b5370 100644 --- a/src/lib/api-error.ts +++ b/src/lib/api-error.ts @@ -107,12 +107,15 @@ export function getErrorTranslationKey(errorCode: number): TranslationKey | null case 5012: return "error_codes.announcement_not_received"; case 5013: return "error_codes.attachment_storage_failed"; case 5014: return "error_codes.stock_quote_failed"; + case 5015: return "error_codes.video_preparation_failed"; + case 5016: return "error_codes.video_generation_failed"; case 6001: return "error_codes.user_limit_reached"; case 6002: return "error_codes.insufficient_credits"; // legacy, moved to 1034 case 6003: return "error_codes.stock_quote_rate_limited"; case 7001: return "error_codes.unsupported_chat_type"; case 7002: return "error_codes.unsupported_provider"; case 7003: return "error_codes.missing_chat_context"; + case 7004: return "error_codes.video_runtime_missing"; case 8001: return "error_codes.di_dependency_not_met"; case 8003: return "error_codes.platform_mapping_failed"; case 8004: return "error_codes.no_attachment_instance"; diff --git a/src/lib/translation-keys.ts b/src/lib/translation-keys.ts index ee8b49f8..a5f6d774 100644 --- a/src/lib/translation-keys.ts +++ b/src/lib/translation-keys.ts @@ -135,6 +135,8 @@ export type TranslationKey = | "usage.context_ids.status_label" | "usage.context_ids.status_completed" | "usage.context_ids.status_failed" + | "usage.context_ids.output_video_size" + | "usage.context_ids.output_video_duration" | "usage.transfer.to" | "usage.transfer.from" | "usage.transfer.note" @@ -308,6 +310,8 @@ export type TranslationKey = | "tools.types.credit_transfer.description" | "tools.types.deprecated.title" | "tools.types.deprecated.description" + | "tools.types.videos_gen.title" + | "tools.types.videos_gen.description" | "intelligence_warnings.no_access_message" | "intelligence_warnings.no_settings" | "intelligence_presets.lowest_price" @@ -427,6 +431,9 @@ export type TranslationKey = | "error_codes.stock_quote_not_found" | "error_codes.stock_quote_failed" | "error_codes.stock_quote_rate_limited" + | "error_codes.video_preparation_failed" + | "error_codes.video_generation_failed" + | "error_codes.video_runtime_missing" | "features.header" | "features.title" | "features.items.language_intelligence.title" @@ -485,6 +492,10 @@ export type TranslationKey = | "cost_estimate.second_of_runtime" | "cost_estimate.web_search_query" | "cost_estimate.max_input_images" + | "cost_estimate.output_video_costs" + | "cost_estimate.output_video_1k_second" + | "cost_estimate.output_video_2k_second" + | "cost_estimate.output_video_4k_second" | "onboarding.page_title" | "onboarding.interface_language_label" | "onboarding.policy_prefix" diff --git a/src/services/external-tools-service.ts b/src/services/external-tools-service.ts index 2f1e3173..5791b796 100644 --- a/src/services/external-tools-service.ts +++ b/src/services/external-tools-service.ts @@ -10,6 +10,7 @@ export type ToolType = | "hearing" | "images_gen" | "images_edit" + | "videos_gen" | "search" | "embedding" | "api_fiat_exchange" @@ -31,6 +32,9 @@ export interface CostEstimate { output_image_1k?: number; output_image_2k?: number; output_image_4k?: number; + output_video_1k_second?: number | null; + output_video_2k_second?: number | null; + output_video_4k_second?: number | null; api_call?: number; second_of_runtime?: number; web_search_query?: number | null; diff --git a/src/services/usage-service.ts b/src/services/usage-service.ts index 48615ded..866be3b5 100644 --- a/src/services/usage-service.ts +++ b/src/services/usage-service.ts @@ -37,6 +37,8 @@ export interface UsageRecord { total_tokens?: number; output_image_sizes?: string[]; input_image_sizes?: string[]; + output_video_size?: string | null; + output_video_duration_seconds?: number | null; is_failed: boolean; participant_details?: ParticipantDetails; counterpart_id?: string; diff --git a/src/services/user-settings-service.ts b/src/services/user-settings-service.ts index e49449ee..3a0261ba 100644 --- a/src/services/user-settings-service.ts +++ b/src/services/user-settings-service.ts @@ -29,6 +29,7 @@ export interface UserSettings { tool_choice_hearing?: string; tool_choice_images_gen?: string; tool_choice_images_edit?: string; + tool_choice_videos_gen?: string; tool_choice_search?: string; tool_choice_embedding?: string; tool_choice_api_fiat_exchange?: string; @@ -82,6 +83,7 @@ export interface UserSettingsPayload { tool_choice_hearing?: string; tool_choice_images_gen?: string; tool_choice_images_edit?: string; + tool_choice_videos_gen?: string; tool_choice_search?: string; tool_choice_embedding?: string; tool_choice_api_fiat_exchange?: string; @@ -115,6 +117,7 @@ const STRING_FIELDS = [ "tool_choice_hearing", "tool_choice_images_gen", "tool_choice_images_edit", + "tool_choice_videos_gen", "tool_choice_search", "tool_choice_embedding", "tool_choice_api_fiat_exchange", From 69cb9a2ca2642f7f65869ce8da23faffd4d4e582 Mon Sep 17 00:00:00 2001 From: Milos Marinkovic Date: Fri, 31 Jul 2026 20:32:25 +0200 Subject: [PATCH 2/2] Bump version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 920e1e02..1f59c621 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "agent-web", - "version": "5.27.2", + "version": "5.29.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "agent-web", - "version": "5.27.2", + "version": "5.29.0", "dependencies": { "@radix-ui/react-accordion": "^1.2.16", "@radix-ui/react-dialog": "^1.1.19", diff --git a/package.json b/package.json index bbd974dd..10523e59 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "agent-web", "private": true, - "version": "5.27.2", + "version": "5.29.0", "type": "module", "scripts": { "clean": "rm -rf dist .vite node_modules/.vite",