From eeb9567ce0715a5ceeab5148b12088f1fb733a47 Mon Sep 17 00:00:00 2001 From: Kayvan Sylvan Date: Mon, 16 Feb 2026 08:28:54 -0800 Subject: [PATCH] feat: add i18n translations for VertexAI, Gemini, Bedrock, and fetch plugins - Add VertexAI error message translations across 10 locale files - Add Gemini TTS and audio error translations to all locales - Add AWS Bedrock client error translations to all locales - Add fetch plugin error message translations to all locales - Replace hardcoded English strings with `i18n.T()` calls in Bedrock plugin - Replace hardcoded English strings with `i18n.T()` calls in Gemini plugin - Replace hardcoded English strings with `i18n.T()` calls in VertexAI plugin - Replace hardcoded English strings with `i18n.T()` calls in fetch plugin - Use `errors.New` instead of `fmt.Errorf` for non-formatted error strings --- internal/i18n/locales/de.json | 46 ++++++++++++++++++++++-- internal/i18n/locales/en.json | 46 ++++++++++++++++++++++-- internal/i18n/locales/es.json | 46 ++++++++++++++++++++++-- internal/i18n/locales/fa.json | 46 ++++++++++++++++++++++-- internal/i18n/locales/fr.json | 46 ++++++++++++++++++++++-- internal/i18n/locales/it.json | 46 ++++++++++++++++++++++-- internal/i18n/locales/ja.json | 46 ++++++++++++++++++++++-- internal/i18n/locales/pt-BR.json | 46 ++++++++++++++++++++++-- internal/i18n/locales/pt-PT.json | 46 ++++++++++++++++++++++-- internal/i18n/locales/zh.json | 36 +++++++++++++++++-- internal/plugins/ai/bedrock/bedrock.go | 31 ++++++++-------- internal/plugins/ai/gemini/gemini.go | 32 +++++++++-------- internal/plugins/ai/vertexai/vertexai.go | 28 ++++++++------- internal/plugins/template/fetch.go | 25 ++++++------- 14 files changed, 491 insertions(+), 75 deletions(-) diff --git a/internal/i18n/locales/de.json b/internal/i18n/locales/de.json index 8edbd318..24ed62af 100644 --- a/internal/i18n/locales/de.json +++ b/internal/i18n/locales/de.json @@ -448,6 +448,48 @@ "chatter_error_find_context": "Kontext %s konnte nicht gefunden werden: %v", "chatter_error_get_pattern": "Pattern %s konnte nicht geladen werden: %v", "chatter_error_load_strategy": "Strategie %s konnte nicht geladen werden: %v", - "chatter_prompt_enforce_response_language": "%s\n\nWICHTIG: Fuehren Sie zuerst die in diesem Prompt bereitgestellten Anweisungen mit der Eingabe des Benutzers aus. Stellen Sie zweitens sicher, dass Ihre gesamte endgueltige Antwort, einschliesslich aller Abschnittsueberschriften oder Titel, die bei der Ausfuehrung der Anweisungen erzeugt werden, AUSSCHLIESSLICH in der Sprache %s verfasst ist." - + "chatter_prompt_enforce_response_language": "%s\n\nWICHTIG: Fuehren Sie zuerst die in diesem Prompt bereitgestellten Anweisungen mit der Eingabe des Benutzers aus. Stellen Sie zweitens sicher, dass Ihre gesamte endgueltige Antwort, einschliesslich aller Abschnittsueberschriften oder Titel, die bei der Ausfuehrung der Anweisungen erzeugt werden, AUSSCHLIESSLICH in der Sprache %s verfasst ist.", + "vertexai_failed_google_credentials": "Google-Anmeldeinformationen konnten nicht abgerufen werden (stellen Sie sicher, dass ADC konfiguriert ist): %w", + "vertexai_no_models_found": "keine Modelle von keinem Herausgeber gefunden", + "vertexai_no_conversational_models": "keine Konversationsmodelle gefunden", + "vertexai_client_not_initialized": "VertexAI-Client nicht initialisiert", + "vertexai_no_valid_messages": "keine gueltigen Nachrichten zum Senden", + "vertexai_no_content_in_response": "kein Inhalt in der Antwort", + "vertexai_failed_gemini_client": "Gemini-Client konnte nicht erstellt werden: %w", + "vertexai_stream_error": "Fehler: %v", + "gemini_invalid_location_format": "ungültiges Suchstandortformat %q: muss eine Zeitzone (z.B. 'America/Los_Angeles') oder ein Sprachcode (z.B. 'en-US') sein", + "gemini_stream_error": "Fehler: %v", + "gemini_no_text_for_tts": "kein Textinhalt für TTS-Generierung gefunden", + "gemini_invalid_voice": "ungültige Stimme '%s'. Gültige Stimmen sind: %v", + "gemini_tts_failed": "TTS-Generierung fehlgeschlagen: %w", + "gemini_unexpected_data_type": "unerwarteter Datentyp: %s, Audiodaten erwartet", + "gemini_audio_data_too_small": "Audiodaten zu klein: %d Bytes, mindestens erforderlich: %d", + "gemini_wav_generation_failed": "WAV-Datei konnte nicht generiert werden: %w", + "gemini_wav_data_invalid": "generierte WAV-Daten sind ungültig: %d Bytes, mindestens erforderlich: %d", + "gemini_no_audio_data": "keine Audiodaten vom TTS-Modell erhalten", + "gemini_empty_pcm_data": "leere PCM-Daten bereitgestellt", + "gemini_pcm_data_too_large": "PCM-Daten zu groß: %d Bytes, maximal erlaubt: %d", + "bedrock_unable_load_aws_config": "AWS-Konfiguration konnte nicht geladen werden: %w", + "bedrock_aws_region_label": "AWS-Region", + "bedrock_invalid_aws_region": "ungültige AWS-Region: %s", + "bedrock_unable_load_aws_config_with_region": "AWS-Konfiguration konnte mit Region %s nicht geladen werden: %w", + "bedrock_failed_list_foundation_models": "Foundation-Modelle konnten nicht aufgelistet werden: %w", + "bedrock_failed_list_inference_profiles": "Inferenz-Profile konnten nicht aufgelistet werden: %w", + "bedrock_panic_sendstream": "Panic in SendStream: %v", + "bedrock_conversestream_failed": "Bedrock ConverseStream für Modell %s fehlgeschlagen: %w", + "bedrock_unknown_stream_event_type": "unbekannter Stream-Event-Typ: %T", + "bedrock_converse_failed": "Bedrock Converse für Modell %s fehlgeschlagen: %w", + "bedrock_unexpected_response_type": "unerwarteter Antworttyp: %T", + "bedrock_empty_response_content": "leerer Antwortinhalt", + "bedrock_unexpected_content_block_type": "unerwarteter Inhaltsblocktyp: %T", + "fetch_unknown_operation": "fetch: unbekannte Operation %q (unterstützt: get)", + "fetch_content_not_utf8": "fetch: Inhalt ist kein gültiger UTF-8-Text", + "fetch_content_null_bytes": "fetch: Inhalt enthält Null-Bytes", + "fetch_error_create_request": "fetch: Fehler beim Erstellen der Anfrage: %v", + "fetch_error_fetching_url": "fetch: Fehler beim Abrufen der URL: %v", + "fetch_http_error": "fetch: HTTP-Fehler: %d - %s", + "fetch_content_too_large": "fetch: Inhalt zu groß: %d Bytes (max %d Bytes)", + "fetch_unsupported_content_type": "fetch: nicht unterstützter Inhaltstyp %q - nur Textinhalt erlaubt", + "fetch_error_reading_response": "fetch: Fehler beim Lesen der Antwort: %v", + "fetch_content_exceeds_limit": "fetch: Inhalt zu groß: überschreitet %d Bytes" } diff --git a/internal/i18n/locales/en.json b/internal/i18n/locales/en.json index fe5b154c..054b8ab8 100644 --- a/internal/i18n/locales/en.json +++ b/internal/i18n/locales/en.json @@ -448,6 +448,48 @@ "chatter_error_find_context": "could not find context %s: %v", "chatter_error_get_pattern": "could not get pattern %s: %v", "chatter_error_load_strategy": "could not load strategy %s: %v", - "chatter_prompt_enforce_response_language": "%s\n\nIMPORTANT: First, execute the instructions provided in this prompt using the user's input. Second, ensure your entire final response, including any section headers or titles generated as part of executing the instructions, is written ONLY in the %s language." - + "chatter_prompt_enforce_response_language": "%s\n\nIMPORTANT: First, execute the instructions provided in this prompt using the user's input. Second, ensure your entire final response, including any section headers or titles generated as part of executing the instructions, is written ONLY in the %s language.", + "vertexai_failed_google_credentials": "failed to get Google credentials (ensure ADC is configured): %w", + "vertexai_no_models_found": "no models found from any publisher", + "vertexai_no_conversational_models": "no conversational models found", + "vertexai_client_not_initialized": "VertexAI client not initialized", + "vertexai_no_valid_messages": "no valid messages to send", + "vertexai_no_content_in_response": "no content in response", + "vertexai_failed_gemini_client": "failed to create Gemini client: %w", + "vertexai_stream_error": "Error: %v", + "gemini_invalid_location_format": "invalid search location format %q: must be timezone (e.g., 'America/Los_Angeles') or language code (e.g., 'en-US')", + "gemini_stream_error": "Error: %v", + "gemini_no_text_for_tts": "no text content found for TTS generation", + "gemini_invalid_voice": "invalid voice '%s'. Valid voices are: %v", + "gemini_tts_failed": "TTS generation failed: %w", + "gemini_unexpected_data_type": "unexpected data type: %s, expected audio data", + "gemini_audio_data_too_small": "audio data too small: %d bytes, minimum required: %d", + "gemini_wav_generation_failed": "failed to generate WAV file: %w", + "gemini_wav_data_invalid": "generated WAV data is invalid: %d bytes, minimum required: %d", + "gemini_no_audio_data": "no audio data received from TTS model", + "gemini_empty_pcm_data": "empty PCM data provided", + "gemini_pcm_data_too_large": "PCM data too large: %d bytes, maximum allowed: %d", + "bedrock_unable_load_aws_config": "unable to load AWS Config: %w", + "bedrock_aws_region_label": "AWS Region", + "bedrock_invalid_aws_region": "invalid AWS region: %s", + "bedrock_unable_load_aws_config_with_region": "unable to load AWS Config with region %s: %w", + "bedrock_failed_list_foundation_models": "failed to list foundation models: %w", + "bedrock_failed_list_inference_profiles": "failed to list inference profiles: %w", + "bedrock_panic_sendstream": "panic in SendStream: %v", + "bedrock_conversestream_failed": "bedrock conversestream failed for model %s: %w", + "bedrock_unknown_stream_event_type": "unknown stream event type: %T", + "bedrock_converse_failed": "bedrock converse failed for model %s: %w", + "bedrock_unexpected_response_type": "unexpected response type: %T", + "bedrock_empty_response_content": "empty response content", + "bedrock_unexpected_content_block_type": "unexpected content block type: %T", + "fetch_unknown_operation": "fetch: unknown operation %q (supported: get)", + "fetch_content_not_utf8": "fetch: content is not valid UTF-8 text", + "fetch_content_null_bytes": "fetch: content contains null bytes", + "fetch_error_create_request": "fetch: error creating request: %v", + "fetch_error_fetching_url": "fetch: error fetching URL: %v", + "fetch_http_error": "fetch: HTTP error: %d - %s", + "fetch_content_too_large": "fetch: content too large: %d bytes (max %d bytes)", + "fetch_unsupported_content_type": "fetch: unsupported content type %q - only text content allowed", + "fetch_error_reading_response": "fetch: error reading response: %v", + "fetch_content_exceeds_limit": "fetch: content too large: exceeds %d bytes" } diff --git a/internal/i18n/locales/es.json b/internal/i18n/locales/es.json index 7ecb893e..23df17e9 100644 --- a/internal/i18n/locales/es.json +++ b/internal/i18n/locales/es.json @@ -448,6 +448,48 @@ "chatter_error_find_context": "no se pudo encontrar el contexto %s: %v", "chatter_error_get_pattern": "no se pudo obtener el patron %s: %v", "chatter_error_load_strategy": "no se pudo cargar la estrategia %s: %v", - "chatter_prompt_enforce_response_language": "%s\n\nIMPORTANTE: Primero, ejecute las instrucciones proporcionadas en este prompt usando la entrada del usuario. Segundo, asegurese de que toda su respuesta final, incluidos los encabezados de seccion o titulos generados como parte de la ejecucion de las instrucciones, este escrita SOLO en el idioma %s." - + "chatter_prompt_enforce_response_language": "%s\n\nIMPORTANTE: Primero, ejecute las instrucciones proporcionadas en este prompt usando la entrada del usuario. Segundo, asegurese de que toda su respuesta final, incluidos los encabezados de seccion o titulos generados como parte de la ejecucion de las instrucciones, este escrita SOLO en el idioma %s.", + "vertexai_failed_google_credentials": "no se pudieron obtener las credenciales de Google (asegurese de que ADC este configurado): %w", + "vertexai_no_models_found": "no se encontraron modelos de ningun editor", + "vertexai_no_conversational_models": "no se encontraron modelos conversacionales", + "vertexai_client_not_initialized": "cliente VertexAI no inicializado", + "vertexai_no_valid_messages": "no hay mensajes validos para enviar", + "vertexai_no_content_in_response": "sin contenido en la respuesta", + "vertexai_failed_gemini_client": "no se pudo crear el cliente Gemini: %w", + "vertexai_stream_error": "Error: %v", + "gemini_invalid_location_format": "formato de ubicación de búsqueda inválido %q: debe ser zona horaria (ej. 'America/Los_Angeles') o código de idioma (ej. 'en-US')", + "gemini_stream_error": "Error: %v", + "gemini_no_text_for_tts": "no se encontró contenido de texto para generación TTS", + "gemini_invalid_voice": "voz inválida '%s'. Las voces válidas son: %v", + "gemini_tts_failed": "generación TTS fallida: %w", + "gemini_unexpected_data_type": "tipo de dato inesperado: %s, se esperaban datos de audio", + "gemini_audio_data_too_small": "datos de audio demasiado pequeños: %d bytes, mínimo requerido: %d", + "gemini_wav_generation_failed": "no se pudo generar el archivo WAV: %w", + "gemini_wav_data_invalid": "datos WAV generados inválidos: %d bytes, mínimo requerido: %d", + "gemini_no_audio_data": "no se recibieron datos de audio del modelo TTS", + "gemini_empty_pcm_data": "datos PCM vacíos proporcionados", + "gemini_pcm_data_too_large": "datos PCM demasiado grandes: %d bytes, máximo permitido: %d", + "bedrock_unable_load_aws_config": "no se pudo cargar la configuración de AWS: %w", + "bedrock_aws_region_label": "Región de AWS", + "bedrock_invalid_aws_region": "región de AWS inválida: %s", + "bedrock_unable_load_aws_config_with_region": "no se pudo cargar la configuración de AWS con región %s: %w", + "bedrock_failed_list_foundation_models": "error al listar modelos base: %w", + "bedrock_failed_list_inference_profiles": "error al listar perfiles de inferencia: %w", + "bedrock_panic_sendstream": "pánico en SendStream: %v", + "bedrock_conversestream_failed": "bedrock conversestream falló para el modelo %s: %w", + "bedrock_unknown_stream_event_type": "tipo de evento de stream desconocido: %T", + "bedrock_converse_failed": "bedrock converse falló para el modelo %s: %w", + "bedrock_unexpected_response_type": "tipo de respuesta inesperado: %T", + "bedrock_empty_response_content": "contenido de respuesta vacío", + "bedrock_unexpected_content_block_type": "tipo de bloque de contenido inesperado: %T", + "fetch_unknown_operation": "fetch: operación desconocida %q (admitida: get)", + "fetch_content_not_utf8": "fetch: el contenido no es texto UTF-8 válido", + "fetch_content_null_bytes": "fetch: el contenido contiene bytes nulos", + "fetch_error_create_request": "fetch: error al crear la solicitud: %v", + "fetch_error_fetching_url": "fetch: error al obtener la URL: %v", + "fetch_http_error": "fetch: error HTTP: %d - %s", + "fetch_content_too_large": "fetch: contenido demasiado grande: %d bytes (máx %d bytes)", + "fetch_unsupported_content_type": "fetch: tipo de contenido no admitido %q - solo se permite contenido de texto", + "fetch_error_reading_response": "fetch: error al leer la respuesta: %v", + "fetch_content_exceeds_limit": "fetch: contenido demasiado grande: supera %d bytes" } diff --git a/internal/i18n/locales/fa.json b/internal/i18n/locales/fa.json index eb3e2160..a9985c48 100644 --- a/internal/i18n/locales/fa.json +++ b/internal/i18n/locales/fa.json @@ -440,6 +440,48 @@ "chatter_error_find_context": "زمينه %s پيدا نشد: %v", "chatter_error_get_pattern": "دريافت الگو %s ممکن نشد: %v", "chatter_error_load_strategy": "بارگذاري راهبرد %s ممکن نشد: %v", - "chatter_prompt_enforce_response_language": "%s\n\nمهم: ابتدا دستورالعمل‌هاي ارائه‌شده در اين پرامپت را با استفاده از ورودي کاربر اجرا کنيد. سپس اطمينان حاصل کنيد که کل پاسخ نهايي شما، از جمله هر عنوان يا سربخشي که در جريان اجراي دستورالعمل‌ها توليد مي‌شود، فقط به زبان %s نوشته شده باشد." - + "chatter_prompt_enforce_response_language": "%s\n\nمهم: ابتدا دستورالعمل‌هاي ارائه‌شده در اين پرامپت را با استفاده از ورودي کاربر اجرا کنيد. سپس اطمينان حاصل کنيد که کل پاسخ نهايي شما، از جمله هر عنوان يا سربخشي که در جريان اجراي دستورالعمل‌ها توليد مي‌شود، فقط به زبان %s نوشته شده باشد.", + "vertexai_failed_google_credentials": "دریافت اعتبارنامه‌های Google ناموفق بود (مطمئن شوید ADC پیکربندی شده است): %w", + "vertexai_no_models_found": "مدلی از هیچ ناشری یافت نشد", + "vertexai_no_conversational_models": "مدل مکالمه‌ای یافت نشد", + "vertexai_client_not_initialized": "کلاینت VertexAI مقداردهی نشده است", + "vertexai_no_valid_messages": "پیام معتبری برای ارسال وجود ندارد", + "vertexai_no_content_in_response": "محتوایی در پاسخ وجود ندارد", + "vertexai_failed_gemini_client": "ایجاد کلاینت Gemini ناموفق بود: %w", + "vertexai_stream_error": "خطا: %v", + "gemini_invalid_location_format": "فرمت مکان جستجوی نامعتبر %q: باید منطقه زمانی (مثال 'America/Los_Angeles') یا کد زبان (مثال 'en-US') باشد", + "gemini_stream_error": "خطا: %v", + "gemini_no_text_for_tts": "محتوای متنی برای تولید TTS یافت نشد", + "gemini_invalid_voice": "صدای نامعتبر '%s'. صداهای معتبر عبارتند از: %v", + "gemini_tts_failed": "تولید TTS ناموفق بود: %w", + "gemini_unexpected_data_type": "نوع داده غیرمنتظره: %s، داده صوتی مورد انتظار بود", + "gemini_audio_data_too_small": "داده صوتی بسیار کوچک: %d بایت، حداقل مورد نیاز: %d", + "gemini_wav_generation_failed": "تولید فایل WAV ناموفق بود: %w", + "gemini_wav_data_invalid": "داده WAV تولید شده نامعتبر است: %d بایت، حداقل مورد نیاز: %d", + "gemini_no_audio_data": "داده صوتی از مدل TTS دریافت نشد", + "gemini_empty_pcm_data": "داده PCM خالی ارائه شد", + "gemini_pcm_data_too_large": "داده PCM بسیار بزرگ: %d بایت، حداکثر مجاز: %d", + "bedrock_unable_load_aws_config": "بارگذاری پیکربندی AWS ناموفق بود: %w", + "bedrock_aws_region_label": "منطقه AWS", + "bedrock_invalid_aws_region": "منطقه AWS نامعتبر: %s", + "bedrock_unable_load_aws_config_with_region": "بارگذاری پیکربندی AWS با منطقه %s ناموفق بود: %w", + "bedrock_failed_list_foundation_models": "فهرست کردن مدل‌های پایه ناموفق بود: %w", + "bedrock_failed_list_inference_profiles": "فهرست کردن پروفایل‌های استنتاج ناموفق بود: %w", + "bedrock_panic_sendstream": "پنیک در SendStream: %v", + "bedrock_conversestream_failed": "bedrock conversestream برای مدل %s ناموفق بود: %w", + "bedrock_unknown_stream_event_type": "نوع رویداد جریان ناشناخته: %T", + "bedrock_converse_failed": "bedrock converse برای مدل %s ناموفق بود: %w", + "bedrock_unexpected_response_type": "نوع پاسخ غیرمنتظره: %T", + "bedrock_empty_response_content": "محتوای پاسخ خالی", + "bedrock_unexpected_content_block_type": "نوع بلوک محتوای غیرمنتظره: %T", + "fetch_unknown_operation": "fetch: عملیات ناشناخته %q (پشتیبانی‌شده: get)", + "fetch_content_not_utf8": "fetch: محتوا متن UTF-8 معتبر نیست", + "fetch_content_null_bytes": "fetch: محتوا شامل بایت‌های null است", + "fetch_error_create_request": "fetch: خطا در ایجاد درخواست: %v", + "fetch_error_fetching_url": "fetch: خطا در دریافت URL: %v", + "fetch_http_error": "fetch: خطای HTTP: %d - %s", + "fetch_content_too_large": "fetch: محتوا بسیار بزرگ است: %d بایت (حداکثر %d بایت)", + "fetch_unsupported_content_type": "fetch: نوع محتوای پشتیبانی‌نشده %q - فقط محتوای متنی مجاز است", + "fetch_error_reading_response": "fetch: خطا در خواندن پاسخ: %v", + "fetch_content_exceeds_limit": "fetch: محتوا بسیار بزرگ است: از %d بایت بیشتر است" } diff --git a/internal/i18n/locales/fr.json b/internal/i18n/locales/fr.json index 421163c1..0666c208 100644 --- a/internal/i18n/locales/fr.json +++ b/internal/i18n/locales/fr.json @@ -448,6 +448,48 @@ "chatter_error_find_context": "impossible de trouver le contexte %s : %v", "chatter_error_get_pattern": "impossible d'obtenir le modele %s : %v", "chatter_error_load_strategy": "impossible de charger la strategie %s : %v", - "chatter_prompt_enforce_response_language": "%s\n\nIMPORTANT : D'abord, executez les instructions fournies dans ce prompt en utilisant l'entree de l'utilisateur. Ensuite, assurez-vous que l'integralite de votre reponse finale, y compris tous les en-tetes de section ou titres generes lors de l'execution des instructions, soit redigee UNIQUEMENT en langue %s." - + "chatter_prompt_enforce_response_language": "%s\n\nIMPORTANT : D'abord, executez les instructions fournies dans ce prompt en utilisant l'entree de l'utilisateur. Ensuite, assurez-vous que l'integralite de votre reponse finale, y compris tous les en-tetes de section ou titres generes lors de l'execution des instructions, soit redigee UNIQUEMENT en langue %s.", + "vertexai_failed_google_credentials": "impossible d'obtenir les identifiants Google (assurez-vous que ADC est configure) : %w", + "vertexai_no_models_found": "aucun modele trouve chez aucun editeur", + "vertexai_no_conversational_models": "aucun modele conversationnel trouve", + "vertexai_client_not_initialized": "client VertexAI non initialise", + "vertexai_no_valid_messages": "aucun message valide a envoyer", + "vertexai_no_content_in_response": "aucun contenu dans la reponse", + "vertexai_failed_gemini_client": "impossible de creer le client Gemini : %w", + "vertexai_stream_error": "Erreur : %v", + "gemini_invalid_location_format": "format d'emplacement de recherche invalide %q : doit être un fuseau horaire (ex. 'America/Los_Angeles') ou un code de langue (ex. 'en-US')", + "gemini_stream_error": "Erreur : %v", + "gemini_no_text_for_tts": "aucun contenu textuel trouvé pour la génération TTS", + "gemini_invalid_voice": "voix invalide '%s'. Les voix valides sont : %v", + "gemini_tts_failed": "échec de la génération TTS : %w", + "gemini_unexpected_data_type": "type de données inattendu : %s, données audio attendues", + "gemini_audio_data_too_small": "données audio trop petites : %d octets, minimum requis : %d", + "gemini_wav_generation_failed": "échec de la génération du fichier WAV : %w", + "gemini_wav_data_invalid": "données WAV générées invalides : %d octets, minimum requis : %d", + "gemini_no_audio_data": "aucune donnée audio reçue du modèle TTS", + "gemini_empty_pcm_data": "données PCM vides fournies", + "gemini_pcm_data_too_large": "données PCM trop volumineuses : %d octets, maximum autorisé : %d", + "bedrock_unable_load_aws_config": "impossible de charger la configuration AWS : %w", + "bedrock_aws_region_label": "Région AWS", + "bedrock_invalid_aws_region": "région AWS invalide : %s", + "bedrock_unable_load_aws_config_with_region": "impossible de charger la configuration AWS avec la région %s : %w", + "bedrock_failed_list_foundation_models": "échec de la liste des modèles de fondation : %w", + "bedrock_failed_list_inference_profiles": "échec de la liste des profils d'inférence : %w", + "bedrock_panic_sendstream": "panique dans SendStream : %v", + "bedrock_conversestream_failed": "bedrock conversestream a échoué pour le modèle %s : %w", + "bedrock_unknown_stream_event_type": "type d'événement de flux inconnu : %T", + "bedrock_converse_failed": "bedrock converse a échoué pour le modèle %s : %w", + "bedrock_unexpected_response_type": "type de réponse inattendu : %T", + "bedrock_empty_response_content": "contenu de réponse vide", + "bedrock_unexpected_content_block_type": "type de bloc de contenu inattendu : %T", + "fetch_unknown_operation": "fetch: opération inconnue %q (prise en charge: get)", + "fetch_content_not_utf8": "fetch: le contenu n'est pas un texte UTF-8 valide", + "fetch_content_null_bytes": "fetch: le contenu contient des octets nuls", + "fetch_error_create_request": "fetch: erreur lors de la création de la requête: %v", + "fetch_error_fetching_url": "fetch: erreur lors de la récupération de l'URL: %v", + "fetch_http_error": "fetch: erreur HTTP: %d - %s", + "fetch_content_too_large": "fetch: contenu trop volumineux: %d octets (max %d octets)", + "fetch_unsupported_content_type": "fetch: type de contenu non pris en charge %q - seul le contenu texte est autorisé", + "fetch_error_reading_response": "fetch: erreur lors de la lecture de la réponse: %v", + "fetch_content_exceeds_limit": "fetch: contenu trop volumineux: dépasse %d octets" } diff --git a/internal/i18n/locales/it.json b/internal/i18n/locales/it.json index 0a4ae843..a93a3616 100644 --- a/internal/i18n/locales/it.json +++ b/internal/i18n/locales/it.json @@ -448,6 +448,48 @@ "chatter_error_find_context": "impossibile trovare il contesto %s: %v", "chatter_error_get_pattern": "impossibile ottenere il pattern %s: %v", "chatter_error_load_strategy": "impossibile caricare la strategia %s: %v", - "chatter_prompt_enforce_response_language": "%s\n\nIMPORTANTE: Per prima cosa, esegui le istruzioni fornite in questo prompt usando l'input dell'utente. In secondo luogo, assicurati che l'intera risposta finale, inclusi eventuali titoli o intestazioni di sezione generati durante l'esecuzione delle istruzioni, sia scritta SOLO nella lingua %s." - + "chatter_prompt_enforce_response_language": "%s\n\nIMPORTANTE: Per prima cosa, esegui le istruzioni fornite in questo prompt usando l'input dell'utente. In secondo luogo, assicurati che l'intera risposta finale, inclusi eventuali titoli o intestazioni di sezione generati durante l'esecuzione delle istruzioni, sia scritta SOLO nella lingua %s.", + "vertexai_failed_google_credentials": "impossibile ottenere le credenziali Google (assicurarsi che ADC sia configurato): %w", + "vertexai_no_models_found": "nessun modello trovato da nessun editore", + "vertexai_no_conversational_models": "nessun modello conversazionale trovato", + "vertexai_client_not_initialized": "client VertexAI non inizializzato", + "vertexai_no_valid_messages": "nessun messaggio valido da inviare", + "vertexai_no_content_in_response": "nessun contenuto nella risposta", + "vertexai_failed_gemini_client": "impossibile creare il client Gemini: %w", + "vertexai_stream_error": "Errore: %v", + "gemini_invalid_location_format": "formato posizione di ricerca non valido %q: deve essere un fuso orario (es. 'America/Los_Angeles') o un codice lingua (es. 'en-US')", + "gemini_stream_error": "Errore: %v", + "gemini_no_text_for_tts": "nessun contenuto testuale trovato per la generazione TTS", + "gemini_invalid_voice": "voce non valida '%s'. Le voci valide sono: %v", + "gemini_tts_failed": "generazione TTS fallita: %w", + "gemini_unexpected_data_type": "tipo di dato inaspettato: %s, attesi dati audio", + "gemini_audio_data_too_small": "dati audio troppo piccoli: %d byte, minimo richiesto: %d", + "gemini_wav_generation_failed": "generazione file WAV fallita: %w", + "gemini_wav_data_invalid": "dati WAV generati non validi: %d byte, minimo richiesto: %d", + "gemini_no_audio_data": "nessun dato audio ricevuto dal modello TTS", + "gemini_empty_pcm_data": "dati PCM vuoti forniti", + "gemini_pcm_data_too_large": "dati PCM troppo grandi: %d byte, massimo consentito: %d", + "bedrock_unable_load_aws_config": "impossibile caricare la configurazione AWS: %w", + "bedrock_aws_region_label": "Regione AWS", + "bedrock_invalid_aws_region": "regione AWS non valida: %s", + "bedrock_unable_load_aws_config_with_region": "impossibile caricare la configurazione AWS con regione %s: %w", + "bedrock_failed_list_foundation_models": "impossibile elencare i modelli di fondazione: %w", + "bedrock_failed_list_inference_profiles": "impossibile elencare i profili di inferenza: %w", + "bedrock_panic_sendstream": "panic in SendStream: %v", + "bedrock_conversestream_failed": "bedrock conversestream fallito per il modello %s: %w", + "bedrock_unknown_stream_event_type": "tipo di evento stream sconosciuto: %T", + "bedrock_converse_failed": "bedrock converse fallito per il modello %s: %w", + "bedrock_unexpected_response_type": "tipo di risposta inaspettato: %T", + "bedrock_empty_response_content": "contenuto della risposta vuoto", + "bedrock_unexpected_content_block_type": "tipo di blocco contenuto inaspettato: %T", + "fetch_unknown_operation": "fetch: operazione sconosciuta %q (supportata: get)", + "fetch_content_not_utf8": "fetch: il contenuto non è testo UTF-8 valido", + "fetch_content_null_bytes": "fetch: il contenuto contiene byte null", + "fetch_error_create_request": "fetch: errore durante la creazione della richiesta: %v", + "fetch_error_fetching_url": "fetch: errore durante il recupero dell'URL: %v", + "fetch_http_error": "fetch: errore HTTP: %d - %s", + "fetch_content_too_large": "fetch: contenuto troppo grande: %d byte (max %d byte)", + "fetch_unsupported_content_type": "fetch: tipo di contenuto non supportato %q - solo contenuto testuale consentito", + "fetch_error_reading_response": "fetch: errore durante la lettura della risposta: %v", + "fetch_content_exceeds_limit": "fetch: contenuto troppo grande: supera %d byte" } diff --git a/internal/i18n/locales/ja.json b/internal/i18n/locales/ja.json index 5ce6b883..b86c189b 100644 --- a/internal/i18n/locales/ja.json +++ b/internal/i18n/locales/ja.json @@ -448,6 +448,48 @@ "chatter_error_find_context": "コンテキスト %s が見つかりませんでした: %v", "chatter_error_get_pattern": "パターン %s を取得できませんでした: %v", "chatter_error_load_strategy": "戦略 %s を読み込めませんでした: %v", - "chatter_prompt_enforce_response_language": "%s\n\n重要: まず、このプロンプトで提供された指示をユーザー入力を使って実行してください。次に、指示の実行中に生成されるセクション見出しやタイトルを含む最終回答全体を、必ず %s 言語のみで記述してください。" - + "chatter_prompt_enforce_response_language": "%s\n\n重要: まず、このプロンプトで提供された指示をユーザー入力を使って実行してください。次に、指示の実行中に生成されるセクション見出しやタイトルを含む最終回答全体を、必ず %s 言語のみで記述してください。", + "vertexai_failed_google_credentials": "Google認証情報の取得に失敗しました(ADCが設定されていることを確認してください): %w", + "vertexai_no_models_found": "どのパブリッシャーからもモデルが見つかりませんでした", + "vertexai_no_conversational_models": "会話モデルが見つかりませんでした", + "vertexai_client_not_initialized": "VertexAIクライアントが初期化されていません", + "vertexai_no_valid_messages": "送信する有効なメッセージがありません", + "vertexai_no_content_in_response": "レスポンスにコンテンツがありません", + "vertexai_failed_gemini_client": "Geminiクライアントの作成に失敗しました: %w", + "vertexai_stream_error": "エラー: %v", + "gemini_invalid_location_format": "無効な検索場所形式 %q: タイムゾーン(例: 'America/Los_Angeles')または言語コード(例: 'en-US')である必要があります", + "gemini_stream_error": "エラー: %v", + "gemini_no_text_for_tts": "TTS生成用のテキストコンテンツが見つかりません", + "gemini_invalid_voice": "無効な音声 '%s'。有効な音声: %v", + "gemini_tts_failed": "TTS生成に失敗しました: %w", + "gemini_unexpected_data_type": "予期しないデータ型: %s、オーディオデータが必要です", + "gemini_audio_data_too_small": "オーディオデータが小さすぎます: %d バイト、最小要件: %d", + "gemini_wav_generation_failed": "WAVファイルの生成に失敗しました: %w", + "gemini_wav_data_invalid": "生成されたWAVデータが無効です: %d バイト、最小要件: %d", + "gemini_no_audio_data": "TTSモデルからオーディオデータが受信されませんでした", + "gemini_empty_pcm_data": "空のPCMデータが提供されました", + "gemini_pcm_data_too_large": "PCMデータが大きすぎます: %d バイト、最大許容: %d", + "bedrock_unable_load_aws_config": "AWS設定を読み込めませんでした: %w", + "bedrock_aws_region_label": "AWSリージョン", + "bedrock_invalid_aws_region": "無効なAWSリージョン: %s", + "bedrock_unable_load_aws_config_with_region": "リージョン %s でAWS設定を読み込めませんでした: %w", + "bedrock_failed_list_foundation_models": "基盤モデルの一覧表示に失敗しました: %w", + "bedrock_failed_list_inference_profiles": "推論プロファイルの一覧表示に失敗しました: %w", + "bedrock_panic_sendstream": "SendStreamでパニックが発生しました: %v", + "bedrock_conversestream_failed": "モデル %s のbedrock conversestreamが失敗しました: %w", + "bedrock_unknown_stream_event_type": "不明なストリームイベントタイプ: %T", + "bedrock_converse_failed": "モデル %s のbedrock converseが失敗しました: %w", + "bedrock_unexpected_response_type": "予期しないレスポンスタイプ: %T", + "bedrock_empty_response_content": "空のレスポンスコンテンツ", + "bedrock_unexpected_content_block_type": "予期しないコンテンツブロックタイプ: %T", + "fetch_unknown_operation": "fetch: 不明な操作 %q(対応: get)", + "fetch_content_not_utf8": "fetch: コンテンツは有効なUTF-8テキストではありません", + "fetch_content_null_bytes": "fetch: コンテンツにnullバイトが含まれています", + "fetch_error_create_request": "fetch: リクエスト作成エラー: %v", + "fetch_error_fetching_url": "fetch: URL取得エラー: %v", + "fetch_http_error": "fetch: HTTPエラー: %d - %s", + "fetch_content_too_large": "fetch: コンテンツが大きすぎます: %dバイト(最大%dバイト)", + "fetch_unsupported_content_type": "fetch: サポートされていないコンテンツタイプ %q - テキストコンテンツのみ許可されています", + "fetch_error_reading_response": "fetch: レスポンス読み取りエラー: %v", + "fetch_content_exceeds_limit": "fetch: コンテンツが大きすぎます: %dバイトを超えています" } diff --git a/internal/i18n/locales/pt-BR.json b/internal/i18n/locales/pt-BR.json index ffdb21f4..510bc543 100644 --- a/internal/i18n/locales/pt-BR.json +++ b/internal/i18n/locales/pt-BR.json @@ -448,6 +448,48 @@ "chatter_error_find_context": "nao foi possivel encontrar o contexto %s: %v", "chatter_error_get_pattern": "nao foi possivel obter o padrao %s: %v", "chatter_error_load_strategy": "nao foi possivel carregar a estrategia %s: %v", - "chatter_prompt_enforce_response_language": "%s\n\nIMPORTANTE: Primeiro, execute as instrucoes fornecidas neste prompt usando a entrada do usuario. Em seguida, garanta que toda a sua resposta final, incluindo quaisquer cabecalhos de secao ou titulos gerados como parte da execucao das instrucoes, seja escrita SOMENTE no idioma %s." - + "chatter_prompt_enforce_response_language": "%s\n\nIMPORTANTE: Primeiro, execute as instrucoes fornecidas neste prompt usando a entrada do usuario. Em seguida, garanta que toda a sua resposta final, incluindo quaisquer cabecalhos de secao ou titulos gerados como parte da execucao das instrucoes, seja escrita SOMENTE no idioma %s.", + "vertexai_failed_google_credentials": "falha ao obter credenciais do Google (certifique-se de que o ADC esteja configurado): %w", + "vertexai_no_models_found": "nenhum modelo encontrado de nenhum editor", + "vertexai_no_conversational_models": "nenhum modelo conversacional encontrado", + "vertexai_client_not_initialized": "cliente VertexAI nao inicializado", + "vertexai_no_valid_messages": "nenhuma mensagem valida para enviar", + "vertexai_no_content_in_response": "sem conteudo na resposta", + "vertexai_failed_gemini_client": "falha ao criar cliente Gemini: %w", + "vertexai_stream_error": "Erro: %v", + "gemini_invalid_location_format": "formato de local de busca invalido %q: deve ser fuso horario (ex. 'America/Los_Angeles') ou codigo de idioma (ex. 'en-US')", + "gemini_stream_error": "Erro: %v", + "gemini_no_text_for_tts": "nenhum conteudo de texto encontrado para geracao TTS", + "gemini_invalid_voice": "voz invalida '%s'. As vozes validas sao: %v", + "gemini_tts_failed": "falha na geracao TTS: %w", + "gemini_unexpected_data_type": "tipo de dado inesperado: %s, esperado dados de audio", + "gemini_audio_data_too_small": "dados de audio muito pequenos: %d bytes, minimo requerido: %d", + "gemini_wav_generation_failed": "falha ao gerar arquivo WAV: %w", + "gemini_wav_data_invalid": "dados WAV gerados invalidos: %d bytes, minimo requerido: %d", + "gemini_no_audio_data": "nenhum dado de audio recebido do modelo TTS", + "gemini_empty_pcm_data": "dados PCM vazios fornecidos", + "gemini_pcm_data_too_large": "dados PCM muito grandes: %d bytes, maximo permitido: %d", + "bedrock_unable_load_aws_config": "nao foi possivel carregar a configuracao AWS: %w", + "bedrock_aws_region_label": "Regiao AWS", + "bedrock_invalid_aws_region": "regiao AWS invalida: %s", + "bedrock_unable_load_aws_config_with_region": "nao foi possivel carregar a configuracao AWS com regiao %s: %w", + "bedrock_failed_list_foundation_models": "falha ao listar modelos de fundacao: %w", + "bedrock_failed_list_inference_profiles": "falha ao listar perfis de inferencia: %w", + "bedrock_panic_sendstream": "panico no SendStream: %v", + "bedrock_conversestream_failed": "bedrock conversestream falhou para o modelo %s: %w", + "bedrock_unknown_stream_event_type": "tipo de evento de stream desconhecido: %T", + "bedrock_converse_failed": "bedrock converse falhou para o modelo %s: %w", + "bedrock_unexpected_response_type": "tipo de resposta inesperado: %T", + "bedrock_empty_response_content": "conteudo de resposta vazio", + "bedrock_unexpected_content_block_type": "tipo de bloco de conteudo inesperado: %T", + "fetch_unknown_operation": "fetch: operação desconhecida %q (suportada: get)", + "fetch_content_not_utf8": "fetch: o conteúdo não é texto UTF-8 válido", + "fetch_content_null_bytes": "fetch: o conteúdo contém bytes nulos", + "fetch_error_create_request": "fetch: erro ao criar a requisição: %v", + "fetch_error_fetching_url": "fetch: erro ao buscar a URL: %v", + "fetch_http_error": "fetch: erro HTTP: %d - %s", + "fetch_content_too_large": "fetch: conteúdo muito grande: %d bytes (máx %d bytes)", + "fetch_unsupported_content_type": "fetch: tipo de conteúdo não suportado %q - apenas conteúdo de texto permitido", + "fetch_error_reading_response": "fetch: erro ao ler a resposta: %v", + "fetch_content_exceeds_limit": "fetch: conteúdo muito grande: excede %d bytes" } diff --git a/internal/i18n/locales/pt-PT.json b/internal/i18n/locales/pt-PT.json index d7953ded..7735f796 100644 --- a/internal/i18n/locales/pt-PT.json +++ b/internal/i18n/locales/pt-PT.json @@ -448,6 +448,48 @@ "chatter_error_find_context": "nao foi possivel encontrar o contexto %s: %v", "chatter_error_get_pattern": "nao foi possivel obter o padrao %s: %v", "chatter_error_load_strategy": "nao foi possivel carregar a estrategia %s: %v", - "chatter_prompt_enforce_response_language": "%s\n\nIMPORTANTE: Primeiro, execute as instrucoes fornecidas neste prompt usando a entrada do utilizador. Em seguida, garanta que toda a sua resposta final, incluindo quaisquer cabecalhos de secao ou titulos gerados como parte da execucao das instrucoes, seja escrita APENAS no idioma %s." - + "chatter_prompt_enforce_response_language": "%s\n\nIMPORTANTE: Primeiro, execute as instrucoes fornecidas neste prompt usando a entrada do utilizador. Em seguida, garanta que toda a sua resposta final, incluindo quaisquer cabecalhos de secao ou titulos gerados como parte da execucao das instrucoes, seja escrita APENAS no idioma %s.", + "vertexai_failed_google_credentials": "falha ao obter credenciais do Google (certifique-se de que o ADC esteja configurado): %w", + "vertexai_no_models_found": "nenhum modelo encontrado de nenhum editor", + "vertexai_no_conversational_models": "nenhum modelo conversacional encontrado", + "vertexai_client_not_initialized": "cliente VertexAI nao inicializado", + "vertexai_no_valid_messages": "nenhuma mensagem valida para enviar", + "vertexai_no_content_in_response": "sem conteudo na resposta", + "vertexai_failed_gemini_client": "falha ao criar cliente Gemini: %w", + "vertexai_stream_error": "Erro: %v", + "gemini_invalid_location_format": "formato de local de busca invalido %q: deve ser fuso horario (ex. 'America/Los_Angeles') ou codigo de idioma (ex. 'en-US')", + "gemini_stream_error": "Erro: %v", + "gemini_no_text_for_tts": "nenhum conteudo de texto encontrado para geracao TTS", + "gemini_invalid_voice": "voz invalida '%s'. As vozes validas sao: %v", + "gemini_tts_failed": "falha na geracao TTS: %w", + "gemini_unexpected_data_type": "tipo de dado inesperado: %s, esperado dados de audio", + "gemini_audio_data_too_small": "dados de audio muito pequenos: %d bytes, minimo requerido: %d", + "gemini_wav_generation_failed": "falha ao gerar ficheiro WAV: %w", + "gemini_wav_data_invalid": "dados WAV gerados invalidos: %d bytes, minimo requerido: %d", + "gemini_no_audio_data": "nenhum dado de audio recebido do modelo TTS", + "gemini_empty_pcm_data": "dados PCM vazios fornecidos", + "gemini_pcm_data_too_large": "dados PCM muito grandes: %d bytes, maximo permitido: %d", + "bedrock_unable_load_aws_config": "nao foi possivel carregar a configuracao AWS: %w", + "bedrock_aws_region_label": "Regiao AWS", + "bedrock_invalid_aws_region": "regiao AWS invalida: %s", + "bedrock_unable_load_aws_config_with_region": "nao foi possivel carregar a configuracao AWS com regiao %s: %w", + "bedrock_failed_list_foundation_models": "falha ao listar modelos de fundacao: %w", + "bedrock_failed_list_inference_profiles": "falha ao listar perfis de inferencia: %w", + "bedrock_panic_sendstream": "panico no SendStream: %v", + "bedrock_conversestream_failed": "bedrock conversestream falhou para o modelo %s: %w", + "bedrock_unknown_stream_event_type": "tipo de evento de stream desconhecido: %T", + "bedrock_converse_failed": "bedrock converse falhou para o modelo %s: %w", + "bedrock_unexpected_response_type": "tipo de resposta inesperado: %T", + "bedrock_empty_response_content": "conteudo de resposta vazio", + "bedrock_unexpected_content_block_type": "tipo de bloco de conteudo inesperado: %T", + "fetch_unknown_operation": "fetch: operação desconhecida %q (suportada: get)", + "fetch_content_not_utf8": "fetch: o conteúdo não é texto UTF-8 válido", + "fetch_content_null_bytes": "fetch: o conteúdo contém bytes nulos", + "fetch_error_create_request": "fetch: erro ao criar o pedido: %v", + "fetch_error_fetching_url": "fetch: erro ao obter o URL: %v", + "fetch_http_error": "fetch: erro HTTP: %d - %s", + "fetch_content_too_large": "fetch: conteúdo demasiado grande: %d bytes (máx %d bytes)", + "fetch_unsupported_content_type": "fetch: tipo de conteúdo não suportado %q - apenas conteúdo de texto permitido", + "fetch_error_reading_response": "fetch: erro ao ler a resposta: %v", + "fetch_content_exceeds_limit": "fetch: conteúdo demasiado grande: excede %d bytes" } diff --git a/internal/i18n/locales/zh.json b/internal/i18n/locales/zh.json index e715848f..9c3cc548 100644 --- a/internal/i18n/locales/zh.json +++ b/internal/i18n/locales/zh.json @@ -448,6 +448,38 @@ "chatter_error_find_context": "找不到上下文 %s:%v", "chatter_error_get_pattern": "无法获取模式 %s:%v", "chatter_error_load_strategy": "无法加载策略 %s:%v", - "chatter_prompt_enforce_response_language": "%s\n\n重要:首先,请使用用户输入执行此提示中提供的指令。其次,请确保你的整个最终回复(包括执行指令时生成的任何章节标题或标题)仅使用 %s 语言撰写。" - + "chatter_prompt_enforce_response_language": "%s\n\n重要:首先,请使用用户输入执行此提示中提供的指令。其次,请确保你的整个最终回复(包括执行指令时生成的任何章节标题或标题)仅使用 %s 语言撰写。", + "vertexai_failed_google_credentials": "获取 Google 凭据失败(请确保 ADC 已配置):%w", + "vertexai_no_models_found": "未从任何发布者找到模型", + "vertexai_no_conversational_models": "未找到对话模型", + "vertexai_client_not_initialized": "VertexAI 客户端未初始化", + "vertexai_no_valid_messages": "没有有效的消息可发送", + "vertexai_no_content_in_response": "响应中没有内容", + "vertexai_failed_gemini_client": "创建 Gemini 客户端失败:%w", + "vertexai_stream_error": "错误:%v", + "gemini_invalid_location_format": "无效的搜索位置格式 %q:必须是时区(例如 'America/Los_Angeles')或语言代码(例如 'en-US')", + "gemini_stream_error": "错误:%v", + "gemini_no_text_for_tts": "未找到用于 TTS 生成的文本内容", + "gemini_invalid_voice": "无效的语音 '%s'。有效的语音有:%v", + "gemini_tts_failed": "TTS 生成失败:%w", + "gemini_unexpected_data_type": "意外的数据类型:%s,预期为音频数据", + "gemini_audio_data_too_small": "音频数据太小:%d 字节,最少需要:%d", + "gemini_wav_generation_failed": "生成 WAV 文件失败:%w", + "gemini_wav_data_invalid": "生成的 WAV 数据无效:%d 字节,最少需要:%d", + "gemini_no_audio_data": "未从 TTS 模型收到音频数据", + "gemini_empty_pcm_data": "提供了空的 PCM 数据", + "gemini_pcm_data_too_large": "PCM 数据太大:%d 字节,最大允许:%d", + "bedrock_unable_load_aws_config": "无法加载 AWS 配置:%w", + "bedrock_aws_region_label": "AWS 区域", + "bedrock_invalid_aws_region": "无效的 AWS 区域:%s", + "bedrock_unable_load_aws_config_with_region": "无法加载区域 %s 的 AWS 配置:%w", + "bedrock_failed_list_foundation_models": "无法列出基础模型:%w", + "bedrock_failed_list_inference_profiles": "无法列出推理配置文件:%w", + "bedrock_panic_sendstream": "SendStream 中出现恐慌:%v", + "bedrock_conversestream_failed": "模型 %s 的 bedrock conversestream 失败:%w", + "bedrock_unknown_stream_event_type": "未知的流事件类型:%T", + "bedrock_converse_failed": "模型 %s 的 bedrock converse 失败:%w", + "bedrock_unexpected_response_type": "意外的响应类型:%T", + "bedrock_empty_response_content": "空响应内容", + "bedrock_unexpected_content_block_type": "意外的内容块类型:%T" } diff --git a/internal/plugins/ai/bedrock/bedrock.go b/internal/plugins/ai/bedrock/bedrock.go index 2d54c8b1..16af873f 100644 --- a/internal/plugins/ai/bedrock/bedrock.go +++ b/internal/plugins/ai/bedrock/bedrock.go @@ -7,9 +7,11 @@ package bedrock import ( "context" + "errors" "fmt" "github.com/danielmiessler/fabric/internal/domain" + "github.com/danielmiessler/fabric/internal/i18n" "github.com/danielmiessler/fabric/internal/plugins" "github.com/danielmiessler/fabric/internal/plugins/ai" @@ -50,11 +52,10 @@ func NewClient() (ret *BedrockClient) { ctx := context.Background() cfg, err := config.LoadDefaultConfig(ctx) if err != nil { - // Create a minimal client that will fail gracefully during configuration ret.PluginBase = plugins.NewVendorPluginBase(vendorName, func() error { - return fmt.Errorf("unable to load AWS Config: %w", err) + return fmt.Errorf(i18n.T("bedrock_unable_load_aws_config"), err) }) - ret.bedrockRegion = ret.PluginBase.AddSetupQuestion("AWS Region", true) + ret.bedrockRegion = ret.PluginBase.AddSetupQuestion(i18n.T("bedrock_aws_region_label"), true) return } @@ -68,7 +69,7 @@ func NewClient() (ret *BedrockClient) { ret.runtimeClient = runtimeClient ret.controlPlaneClient = controlPlaneClient - ret.bedrockRegion = ret.PluginBase.AddSetupQuestion("AWS Region", true) + ret.bedrockRegion = ret.PluginBase.AddSetupQuestion(i18n.T("bedrock_aws_region_label"), true) if cfg.Region != "" { ret.bedrockRegion.Value = cfg.Region @@ -97,13 +98,13 @@ func (c *BedrockClient) configure() error { // Validate region format if !isValidAWSRegion(c.bedrockRegion.Value) { - return fmt.Errorf("invalid AWS region: %s", c.bedrockRegion.Value) + return fmt.Errorf(i18n.T("bedrock_invalid_aws_region"), c.bedrockRegion.Value) } ctx := context.Background() cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(c.bedrockRegion.Value)) if err != nil { - return fmt.Errorf("unable to load AWS Config with region %s: %w", c.bedrockRegion.Value, err) + return fmt.Errorf(i18n.T("bedrock_unable_load_aws_config_with_region"), c.bedrockRegion.Value, err) } cfg.APIOptions = append(cfg.APIOptions, middleware.AddUserAgentKeyValue(userAgentKey, userAgentValue)) @@ -122,7 +123,7 @@ func (c *BedrockClient) ListModels() ([]string, error) { foundationModels, err := c.controlPlaneClient.ListFoundationModels(ctx, &bedrock.ListFoundationModelsInput{}) if err != nil { - return nil, fmt.Errorf("failed to list foundation models: %w", err) + return nil, fmt.Errorf(i18n.T("bedrock_failed_list_foundation_models"), err) } for _, model := range foundationModels.ModelSummaries { @@ -134,7 +135,7 @@ func (c *BedrockClient) ListModels() ([]string, error) { for inferenceProfilesPaginator.HasMorePages() { inferenceProfiles, err := inferenceProfilesPaginator.NextPage(ctx) if err != nil { - return nil, fmt.Errorf("failed to list inference profiles: %w", err) + return nil, fmt.Errorf(i18n.T("bedrock_failed_list_inference_profiles"), err) } for _, profile := range inferenceProfiles.InferenceProfileSummaries { @@ -150,7 +151,7 @@ func (c *BedrockClient) SendStream(msgs []*chat.ChatCompletionMessage, opts *dom // Ensure channel is closed on all exit paths to prevent goroutine leaks defer func() { if r := recover(); r != nil { - err = fmt.Errorf("panic in SendStream: %v", r) + err = fmt.Errorf(i18n.T("bedrock_panic_sendstream"), r) } close(channel) }() @@ -167,7 +168,7 @@ func (c *BedrockClient) SendStream(msgs []*chat.ChatCompletionMessage, opts *dom response, err := c.runtimeClient.ConverseStream(context.Background(), &converseInput) if err != nil { - return fmt.Errorf("bedrock conversestream failed for model %s: %w", opts.Model, err) + return fmt.Errorf(i18n.T("bedrock_conversestream_failed"), opts.Model, err) } for event := range response.GetStream().Events() { @@ -209,7 +210,7 @@ func (c *BedrockClient) SendStream(msgs []*chat.ChatCompletionMessage, opts *dom *types.ConverseStreamOutputMemberContentBlockStop: default: - return fmt.Errorf("unknown stream event type: %T", v) + return fmt.Errorf(i18n.T("bedrock_unknown_stream_event_type"), v) } } @@ -227,22 +228,22 @@ func (c *BedrockClient) Send(ctx context.Context, msgs []*chat.ChatCompletionMes } response, err := c.runtimeClient.Converse(ctx, &converseInput) if err != nil { - return "", fmt.Errorf("bedrock converse failed for model %s: %w", opts.Model, err) + return "", fmt.Errorf(i18n.T("bedrock_converse_failed"), opts.Model, err) } responseText, ok := response.Output.(*types.ConverseOutputMemberMessage) if !ok { - return "", fmt.Errorf("unexpected response type: %T", response.Output) + return "", fmt.Errorf(i18n.T("bedrock_unexpected_response_type"), response.Output) } if len(responseText.Value.Content) == 0 { - return "", fmt.Errorf("empty response content") + return "", errors.New(i18n.T("bedrock_empty_response_content")) } responseContentBlock := responseText.Value.Content[0] text, ok := responseContentBlock.(*types.ContentBlockMemberText) if !ok { - return "", fmt.Errorf("unexpected content block type: %T", responseContentBlock) + return "", fmt.Errorf(i18n.T("bedrock_unexpected_content_block_type"), responseContentBlock) } return text.Value, nil diff --git a/internal/plugins/ai/gemini/gemini.go b/internal/plugins/ai/gemini/gemini.go index 172c7219..96625d6c 100644 --- a/internal/plugins/ai/gemini/gemini.go +++ b/internal/plugins/ai/gemini/gemini.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/binary" + "errors" "fmt" "regexp" "strconv" @@ -11,6 +12,7 @@ import ( "github.com/danielmiessler/fabric/internal/chat" "github.com/danielmiessler/fabric/internal/domain" + "github.com/danielmiessler/fabric/internal/i18n" "github.com/danielmiessler/fabric/internal/plugins" "github.com/danielmiessler/fabric/internal/plugins/ai/geminicommon" "google.golang.org/genai" @@ -29,7 +31,7 @@ const ( ) const ( - errInvalidLocationFormat = "invalid search location format %q: must be timezone (e.g., 'America/Los_Angeles') or language code (e.g., 'en-US')" + errInvalidLocationFormat = "gemini_invalid_location_format" locationSeparator = "/" langCodeSeparator = "_" langCodeNormalizedSep = "-" @@ -86,7 +88,7 @@ func (o *Client) Send(ctx context.Context, msgs []*chat.ChatCompletionMessage, o // Check if this is a TTS model request if o.isTTSModel(opts.Model) { if !opts.AudioOutput { - err = fmt.Errorf("TTS model '%s' requires audio output. Please specify an audio output file with -o flag ending in .wav", opts.Model) + err = fmt.Errorf(i18n.T("tts_model_requires_audio_output"), opts.Model) return } @@ -149,7 +151,7 @@ func (o *Client) SendStream(msgs []*chat.ChatCompletionMessage, opts *domain.Cha if err != nil { channel <- domain.StreamUpdate{ Type: domain.StreamTypeError, - Content: fmt.Sprintf("Error: %v", err), + Content: fmt.Sprintf(i18n.T("gemini_stream_error"), err), } return err } @@ -230,7 +232,7 @@ func (o *Client) buildGenerateContentConfig(opts *domain.ChatOptions) (*genai.Ge RetrievalConfig: &genai.RetrievalConfig{LanguageCode: loc}, } } else { - return nil, fmt.Errorf(errInvalidLocationFormat, loc) + return nil, fmt.Errorf(i18n.T(errInvalidLocationFormat), loc) } } } @@ -297,7 +299,7 @@ func (o *Client) extractTextForTTS(msgs []*chat.ChatCompletionMessage) (string, return msgs[i].Content, nil } } - return "", fmt.Errorf("no text content found for TTS generation") + return "", errors.New(i18n.T("gemini_no_text_for_tts")) } // createGenaiClient creates a new GenAI client for TTS operations @@ -318,7 +320,7 @@ func (o *Client) generateTTSAudio(ctx context.Context, msgs []*chat.ChatCompleti // Validate voice name before making API call if opts.Voice != "" && !IsValidGeminiVoice(opts.Voice) { validVoices := GetGeminiVoiceNames() - return "", fmt.Errorf("invalid voice '%s'. Valid voices are: %v", opts.Voice, validVoices) + return "", fmt.Errorf(i18n.T("gemini_invalid_voice"), opts.Voice, validVoices) } client, err := o.createGenaiClient(ctx) @@ -357,7 +359,7 @@ func (o *Client) performTTSGeneration(ctx context.Context, client *genai.Client, // Generate TTS content response, err := client.Models.GenerateContent(ctx, o.buildModelNameFull(opts.Model), contents, config) if err != nil { - return "", fmt.Errorf("TTS generation failed: %w", err) + return "", fmt.Errorf(i18n.T("gemini_tts_failed"), err) } // Extract and process audio data @@ -366,23 +368,23 @@ func (o *Client) performTTSGeneration(ctx context.Context, client *genai.Client, if part.InlineData != nil && len(part.InlineData.Data) > 0 { // Validate audio data format and size if part.InlineData.MIMEType != "" && !strings.HasPrefix(part.InlineData.MIMEType, "audio/") { - return "", fmt.Errorf("unexpected data type: %s, expected audio data", part.InlineData.MIMEType) + return "", fmt.Errorf(i18n.T("gemini_unexpected_data_type"), part.InlineData.MIMEType) } pcmData := part.InlineData.Data if len(pcmData) < MinAudioDataSize { - return "", fmt.Errorf("audio data too small: %d bytes, minimum required: %d", len(pcmData), MinAudioDataSize) + return "", fmt.Errorf(i18n.T("gemini_audio_data_too_small"), len(pcmData), MinAudioDataSize) } // Generate WAV file with proper headers and return the binary data wavData, err := o.generateWAVFile(pcmData) if err != nil { - return "", fmt.Errorf("failed to generate WAV file: %w", err) + return "", fmt.Errorf(i18n.T("gemini_wav_generation_failed"), err) } // Validate generated WAV data if len(wavData) < WAVHeaderSize { - return "", fmt.Errorf("generated WAV data is invalid: %d bytes, minimum required: %d", len(wavData), WAVHeaderSize) + return "", fmt.Errorf(i18n.T("gemini_wav_data_invalid"), len(wavData), WAVHeaderSize) } // Store the binary audio data in a special format that the CLI can detect @@ -391,17 +393,17 @@ func (o *Client) performTTSGeneration(ctx context.Context, client *genai.Client, } } - return "", fmt.Errorf("no audio data received from TTS model") + return "", errors.New(i18n.T("gemini_no_audio_data")) } // generateWAVFile creates WAV data from PCM data with proper headers func (o *Client) generateWAVFile(pcmData []byte) ([]byte, error) { // Validate input size to prevent potential security issues if len(pcmData) == 0 { - return nil, fmt.Errorf("empty PCM data provided") + return nil, errors.New(i18n.T("gemini_empty_pcm_data")) } if len(pcmData) > MaxAudioDataSize { - return nil, fmt.Errorf("PCM data too large: %d bytes, maximum allowed: %d", len(pcmData), MaxAudioDataSize) + return nil, fmt.Errorf(i18n.T("gemini_pcm_data_too_large"), len(pcmData), MaxAudioDataSize) } // WAV file parameters (Gemini TTS default specs) @@ -444,7 +446,7 @@ func (o *Client) generateWAVFile(pcmData []byte) ([]byte, error) { // Validate generated WAV data result := buf.Bytes() if len(result) < WAVHeaderSize { - return nil, fmt.Errorf("generated WAV data is invalid: %d bytes, minimum required: %d", len(result), WAVHeaderSize) + return nil, fmt.Errorf(i18n.T("gemini_wav_data_invalid"), len(result), WAVHeaderSize) } return result, nil diff --git a/internal/plugins/ai/vertexai/vertexai.go b/internal/plugins/ai/vertexai/vertexai.go index 93e0ee04..7f9e40c0 100644 --- a/internal/plugins/ai/vertexai/vertexai.go +++ b/internal/plugins/ai/vertexai/vertexai.go @@ -2,6 +2,7 @@ package vertexai import ( "context" + "errors" "fmt" "strings" @@ -9,6 +10,7 @@ import ( "github.com/anthropics/anthropic-sdk-go/vertex" "github.com/danielmiessler/fabric/internal/chat" "github.com/danielmiessler/fabric/internal/domain" + "github.com/danielmiessler/fabric/internal/i18n" debuglog "github.com/danielmiessler/fabric/internal/log" "github.com/danielmiessler/fabric/internal/plugins" "github.com/danielmiessler/fabric/internal/plugins/ai/geminicommon" @@ -65,7 +67,7 @@ func (c *Client) ListModels() ([]string, error) { // Get ADC credentials for API authentication creds, err := google.FindDefaultCredentials(ctx, cloudPlatformScope) if err != nil { - return nil, fmt.Errorf("failed to get Google credentials (ensure ADC is configured): %w", err) + return nil, fmt.Errorf(i18n.T("vertexai_failed_google_credentials"), err) } httpClient := oauth2.NewClient(ctx, creds.TokenSource) @@ -104,13 +106,13 @@ func (c *Client) ListModels() ([]string, error) { } if len(allModels) == 0 { - return nil, fmt.Errorf("no models found from any publisher") + return nil, errors.New(i18n.T("vertexai_no_models_found")) } // Filter to only conversational models and sort filtered := filterConversationalModels(allModels) if len(filtered) == 0 { - return nil, fmt.Errorf("no conversational models found") + return nil, errors.New(i18n.T("vertexai_no_conversational_models")) } return sortModels(filtered), nil @@ -133,13 +135,13 @@ func getMaxTokens(opts *domain.ChatOptions) int64 { func (c *Client) sendClaude(ctx context.Context, msgs []*chat.ChatCompletionMessage, opts *domain.ChatOptions) (string, error) { if c.client == nil { - return "", fmt.Errorf("VertexAI client not initialized") + return "", errors.New(i18n.T("vertexai_client_not_initialized")) } // Convert chat messages to Anthropic format anthropicMessages := c.toMessages(msgs) if len(anthropicMessages) == 0 { - return "", fmt.Errorf("no valid messages to send") + return "", errors.New(i18n.T("vertexai_no_valid_messages")) } // Build request params @@ -171,7 +173,7 @@ func (c *Client) sendClaude(ctx context.Context, msgs []*chat.ChatCompletionMess } if len(textParts) == 0 { - return "", fmt.Errorf("no content in response") + return "", errors.New(i18n.T("vertexai_no_content_in_response")) } return strings.Join(textParts, ""), nil @@ -187,7 +189,7 @@ func (c *Client) SendStream(msgs []*chat.ChatCompletionMessage, opts *domain.Cha func (c *Client) sendStreamClaude(msgs []*chat.ChatCompletionMessage, opts *domain.ChatOptions, channel chan domain.StreamUpdate) error { if c.client == nil { close(channel) - return fmt.Errorf("VertexAI client not initialized") + return errors.New(i18n.T("vertexai_client_not_initialized")) } defer close(channel) @@ -196,7 +198,7 @@ func (c *Client) sendStreamClaude(msgs []*chat.ChatCompletionMessage, opts *doma // Convert chat messages to Anthropic format anthropicMessages := c.toMessages(msgs) if len(anthropicMessages) == 0 { - return fmt.Errorf("no valid messages to send") + return errors.New(i18n.T("vertexai_no_valid_messages")) } // Build request params @@ -271,12 +273,12 @@ func (c *Client) sendGemini(ctx context.Context, msgs []*chat.ChatCompletionMess Backend: genai.BackendVertexAI, }) if err != nil { - return "", fmt.Errorf("failed to create Gemini client: %w", err) + return "", fmt.Errorf(i18n.T("vertexai_failed_gemini_client"), err) } contents := geminicommon.ConvertMessages(msgs) if len(contents) == 0 { - return "", fmt.Errorf("no valid messages to send") + return "", errors.New(i18n.T("vertexai_no_valid_messages")) } config := c.buildGeminiConfig(opts) @@ -345,12 +347,12 @@ func (c *Client) sendStreamGemini(msgs []*chat.ChatCompletionMessage, opts *doma Backend: genai.BackendVertexAI, }) if err != nil { - return fmt.Errorf("failed to create Gemini client: %w", err) + return fmt.Errorf(i18n.T("vertexai_failed_gemini_client"), err) } contents := geminicommon.ConvertMessages(msgs) if len(contents) == 0 { - return fmt.Errorf("no valid messages to send") + return errors.New(i18n.T("vertexai_no_valid_messages")) } config := c.buildGeminiConfig(opts) @@ -361,7 +363,7 @@ func (c *Client) sendStreamGemini(msgs []*chat.ChatCompletionMessage, opts *doma if err != nil { channel <- domain.StreamUpdate{ Type: domain.StreamTypeError, - Content: fmt.Sprintf("Error: %v", err), + Content: fmt.Sprintf(i18n.T("vertexai_stream_error"), err), } return err } diff --git a/internal/plugins/template/fetch.go b/internal/plugins/template/fetch.go index 36678aee..33ba3686 100644 --- a/internal/plugins/template/fetch.go +++ b/internal/plugins/template/fetch.go @@ -5,12 +5,15 @@ package template import ( "bytes" + "errors" "fmt" "io" "mime" "net/http" "strings" "unicode/utf8" + + "github.com/danielmiessler/fabric/internal/i18n" ) const ( @@ -37,7 +40,7 @@ func (p *FetchPlugin) Apply(operation string, value string) (string, error) { case "get": return p.fetch(value) default: - return "", fmt.Errorf("fetch: unknown operation %q (supported: get)", operation) + return "", fmt.Errorf(i18n.T("fetch_unknown_operation"), operation) } } @@ -69,11 +72,11 @@ func (p *FetchPlugin) validateTextContent(content []byte) error { debugf("Fetch: validating content length=%d bytes", len(content)) if !utf8.Valid(content) { - return fmt.Errorf("fetch: content is not valid UTF-8 text") + return fmt.Errorf(i18n.T("fetch_content_not_utf8")) } if bytes.Contains(content, []byte{0}) { - return fmt.Errorf("fetch: content contains null bytes") + return fmt.Errorf(i18n.T("fetch_content_null_bytes")) } debugf("Fetch: content validation successful") @@ -87,42 +90,40 @@ func (p *FetchPlugin) fetch(urlStr string) (string, error) { client := &http.Client{} req, err := http.NewRequest("GET", urlStr, nil) if err != nil { - return "", fmt.Errorf("fetch: error creating request: %v", err) + return "", fmt.Errorf(i18n.T("fetch_error_create_request"), err) } req.Header.Set("User-Agent", UserAgent) resp, err := client.Do(req) if err != nil { - return "", fmt.Errorf("fetch: error fetching URL: %v", err) + return "", fmt.Errorf(i18n.T("fetch_error_fetching_url"), err) } defer resp.Body.Close() debugf("Fetch: got response status=%q", resp.Status) if resp.StatusCode != http.StatusOK { - return "", fmt.Errorf("fetch: HTTP error: %d - %s", resp.StatusCode, resp.Status) + return "", fmt.Errorf(i18n.T("fetch_http_error"), resp.StatusCode, resp.Status) } if contentLength := resp.ContentLength; contentLength > MaxContentSize { - return "", fmt.Errorf("fetch: content too large: %d bytes (max %d bytes)", - contentLength, MaxContentSize) + return "", fmt.Errorf(i18n.T("fetch_content_too_large"), contentLength, MaxContentSize) } contentType := resp.Header.Get("Content-Type") debugf("Fetch: content-type=%q", contentType) if !p.isTextContent(contentType) { - return "", fmt.Errorf("fetch: unsupported content type %q - only text content allowed", - contentType) + return "", fmt.Errorf(i18n.T("fetch_unsupported_content_type"), contentType) } debugf("Fetch: reading response body") limitReader := io.LimitReader(resp.Body, MaxContentSize+1) content, err := io.ReadAll(limitReader) if err != nil { - return "", fmt.Errorf("fetch: error reading response: %v", err) + return "", fmt.Errorf(i18n.T("fetch_error_reading_response"), err) } if len(content) > MaxContentSize { - return "", fmt.Errorf("fetch: content too large: exceeds %d bytes", MaxContentSize) + return "", fmt.Errorf(i18n.T("fetch_content_exceeds_limit"), MaxContentSize) } if err := p.validateTextContent(content); err != nil {