fix(webui): stabilize streaming output and settings i18n

This commit is contained in:
Xubin Ren
2026-06-01 00:00:37 +08:00
parent 31722120b7
commit 34386fe676
13 changed files with 1164 additions and 1048 deletions
+130 -130
View File
@@ -59,43 +59,43 @@
"settings": {
"backToChat": "Volver al chat",
"sidebar": {
"title": "Configuración",
"ariaLabel": "Secciones de configuración"
"title": "Ajustes",
"ariaLabel": "Secciones de ajustes"
},
"nav": {
"general": "General",
"byok": "BYOK",
"overview": "Overview",
"appearance": "Appearance",
"models": "Models",
"providers": "Providers",
"image": "Image",
"browser": "Web",
"overview": "Resumen",
"appearance": "Apariencia",
"models": "Modelos",
"providers": "Proveedores",
"image": "Imagen",
"browser": "Internet",
"runtime": "Sistema",
"advanced": "Security",
"advanced": "Seguridad",
"cliApps": "Apps CLI",
"mcp": "MCP",
"apps": "Apps"
"apps": "Aplicaciones"
},
"sections": {
"interface": "Interfaz",
"ai": "IA",
"ai": "AI",
"system": "Sistema",
"status": "Status",
"localPreferences": "Local preferences",
"presets": "Presets",
"status": "Estado",
"localPreferences": "Preferencias locales",
"presets": "Preajustes",
"imageGeneration": "Generación de imágenes",
"imageDefaults": "Valores predeterminados",
"webSearch": "Web search",
"webBehavior": "Behavior",
"identity": "Identity",
"webuiSafety": "Web safety",
"webSearch": "Búsqueda web",
"webBehavior": "Comportamiento",
"identity": "Identidad",
"webuiSafety": "Seguridad de WebUI",
"capabilities": "Capacidades",
"cliApps": "Apps CLI",
"cliApps": "Aplicaciones CLI",
"mcp": "Servicios MCP",
"apps": "Apps",
"nativeHost": "App",
"hostSafety": "App safety"
"apps": "Aplicaciones",
"nativeHost": "Host nativo",
"hostSafety": "Seguridad de la app"
},
"rows": {
"theme": "Tema",
@@ -104,118 +104,118 @@
"model": "Modelo",
"restart": "Reiniciar nanobot",
"configPath": "Ruta de configuración",
"activePreset": "Active preset",
"gateway": "Gateway",
"restartState": "Restart state",
"activePreset": "Preajuste activo",
"gateway": "Pasarela",
"restartState": "Estado de reinicio",
"pendingChanges": "Cambios pendientes",
"selectedPreset": "Selected preset",
"presetModel": "Preset model",
"density": "Density",
"activityMode": "Activity detail",
"codeWrap": "Code wrapping",
"maxResults": "Max results",
"timeout": "Timeout",
"jinaReader": "Jina reader",
"selectedPreset": "Preajuste seleccionado",
"presetModel": "Modelo del preajuste",
"density": "Densidad",
"activityMode": "Detalle de actividad",
"codeWrap": "Ajuste de código",
"maxResults": "Resultados máximos",
"timeout": "Tiempo de espera",
"jinaReader": "Lector Jina",
"imageGeneration": "Generación de imágenes",
"imageProvider": "Proveedor de imágenes",
"imageProviderStatus": "Estado del proveedor",
"imageProviderBase": "Base del proveedor",
"imageModel": "Modelo de imagen",
"defaultAspectRatio": "Relación predeterminada",
"defaultAspectRatio": "Proporción predeterminada",
"defaultImageSize": "Tamaño predeterminado",
"maxImagesPerTurn": "Máximo de imágenes por turno",
"maxImagesPerTurn": "Máx. imágenes por turno",
"imageSaveDir": "Directorio de guardado",
"botName": "Bot name",
"botIcon": "Bot icon",
"timezone": "Timezone",
"botName": "Nombre del bot",
"botIcon": "Icono del bot",
"timezone": "Zona horaria",
"workspacePath": "Workspace predeterminado",
"localServiceAccess": "Local services",
"webuiDefaultAccess": "Default access",
"localServiceAccess": "Servicios locales",
"webuiDefaultAccess": "Acceso predeterminado",
"currentModel": "Configuración actual",
"brandLogos": "Logotipos de marca",
"cliAppsCatalog": "Catálogo de apps CLI",
"cliAppsFilter": "Filtro de apps CLI",
"brandLogos": "Logos de marca",
"cliAppsCatalog": "Catálogo",
"cliAppsFilter": "Filtro",
"engine": "Motor",
"logs": "Registros",
"diagnostics": "Diagnóstico",
"contextWindow": "Context window"
"contextWindow": "Ventana de contexto"
},
"help": {
"theme": "Cambia entre apariencia clara y oscura.",
"language": "Elige el idioma usado por la WebUI.",
"language": "Elige el idioma usado por WebUI.",
"provider": "Selecciona el proveedor para nuevas solicitudes de modelo.",
"model": "Define el nombre del modelo predeterminado que usa nanobot.",
"configPath": "El archivo de configuración que usa actualmente el gateway.",
"selectedPreset": "Named presets are read-only here; edit them in config.json.",
"presetModel": "Switch to Default to edit model and provider from the WebUI.",
"density": "Stored only in this browser.",
"activityMode": "Choose how much agent activity chrome to show by default.",
"codeWrap": "Keep long code lines readable on smaller screens.",
"maxResults": "Results returned by each web_search call.",
"timeout": "Seconds before a search provider request times out.",
"jinaReader": "Use Jina Reader for web_fetch when available.",
"imageGeneration": "Expone generate_image en los chats cuando hay un proveedor de imágenes configurado disponible.",
"imageProvider": "Elige el proveedor del registro que usará generate_image.",
"imageProviderStatus": "La generación de imágenes reutiliza las credenciales de Proveedores.",
"model": "Define el nombre de modelo predeterminado de nanobot.",
"configPath": "Archivo de configuración que usa actualmente el gateway.",
"selectedPreset": "Los preajustes con nombre son de solo lectura aquí; edítalos en config.json.",
"presetModel": "Cambia a Default para editar modelo y proveedor desde WebUI.",
"density": "Solo se guarda en este navegador.",
"activityMode": "Elige cuánto detalle de actividad del agente se muestra por defecto.",
"codeWrap": "Mantiene legibles las líneas largas de código en pantallas pequeñas.",
"maxResults": "Resultados devueltos por cada llamada web_search.",
"timeout": "Segundos antes de que una solicitud de búsqueda expire.",
"jinaReader": "Usa Jina Reader para web_fetch cuando esté disponible.",
"imageGeneration": "Expone generate_image en chats cuando hay un proveedor de imagen configurado.",
"imageProvider": "Elige el proveedor registrado usado por generate_image.",
"imageProviderStatus": "La generación de imágenes reutiliza credenciales de Proveedores.",
"imageModel": "Nombre del modelo enviado al proveedor de imágenes seleccionado.",
"defaultAspectRatio": "Se usa cuando el prompt no elige una relación de aspecto.",
"defaultImageSize": "Sugerencia de tamaño enviada a los proveedores que la admiten.",
"defaultAspectRatio": "Se usa cuando el prompt no elige una proporción.",
"defaultImageSize": "Pista de tamaño enviada a proveedores compatibles.",
"maxImagesPerTurn": "Límite superior para una solicitud generate_image.",
"botName": "Se muestra donde nanobot usa un nombre visible.",
"botIcon": "Emoji o texto corto mostrado junto al nombre del bot.",
"timezone": "Se usa para programaciones y respuestas sensibles al tiempo.",
"localServiceAccess": "Allow Full Access shell commands to reach localhost services.",
"webuiDefaultAccess": "Used by web chats without a project-specific permission.",
"securityManagedControls": "Web fetches always protect local, private, and metadata services. Core channel safety stays in config.json.",
"currentModel": "Elige la configuración de modelo que nanobot usa para las próximas respuestas.",
"selectedModelProvider": "Lo define el modelo seleccionado.",
"selectedModelValue": "Lo define el modelo seleccionado.",
"brandLogos": "Los logotipos se cargan desde los dominios de las marcas con una reserva de icono local.",
"cliAppsCatalog": "Explora CLIs de apps que nanobot puede ejecutar localmente.",
"botIcon": "Emoji o texto corto junto al nombre del bot.",
"timezone": "Se usa para horarios y respuestas con conciencia temporal.",
"localServiceAccess": "Permite que comandos shell con Full Access alcancen servicios localhost.",
"webuiDefaultAccess": "Usado por chats web sin permiso específico de proyecto.",
"securityManagedControls": "Las capturas web siempre protegen servicios locales, privados y metadata. La seguridad de canales core se gestiona en config.json.",
"currentModel": "Se usa para nuevas respuestas.",
"selectedModelProvider": "Definido por el modelo seleccionado.",
"selectedModelValue": "Definido por el modelo seleccionado.",
"brandLogos": "Muestra logos de proveedores de terceros y CLI en Ajustes.",
"cliAppsCatalog": "Instala solo adaptadores CLI de apps que nanobot puede ejecutar localmente; las apps nativas no se modifican.",
"cliAppsFilter": "Busca por app, categoría o capacidad.",
"logs": "Abre la carpeta de registros del motor de escritorio.",
"logs": "Abre la carpeta de registros del motor nativo.",
"diagnostics": "Exporta un pequeño informe de runtime para soporte.",
"localServiceAccessNative": "Allow Full Access shell commands to reach services on this Mac.",
"webuiDefaultAccessNative": "Used by native chats without a project-specific permission.",
"contextWindow": "Choose the default context budget for this model configuration."
"localServiceAccessNative": "Permite que comandos shell con Full Access alcancen servicios en este Mac.",
"webuiDefaultAccessNative": "Usado por chats nativos sin permiso específico de proyecto.",
"contextWindow": "Elige el presupuesto de contexto predeterminado para esta configuración de modelo."
},
"values": {
"light": "Claro",
"dark": "Oscuro",
"notAvailable": "No disponible",
"enabled": "Enabled",
"disabled": "Disabled",
"enabled": "Activado",
"disabled": "Desactivado",
"restartPending": "Reinicio pendiente",
"ready": "Listo",
"comfortable": "Comfortable",
"compact": "Compact",
"auto": "Auto",
"expanded": "Expanded",
"on": "On",
"off": "Off",
"defaultPermission": "Default Permission",
"fullAccess": "Full Access",
"configured": "Configured",
"notConfigured": "Not configured",
"comfortable": "Cómodo",
"compact": "Compacto",
"auto": "Automático",
"expanded": "Expandido",
"on": "Activado",
"off": "Desactivado",
"defaultPermission": "Permiso predeterminado",
"fullAccess": "Acceso completo",
"configured": "Configurado",
"notConfigured": "Sin configurar",
"pending": "Pendiente",
"restartingEngine": "Reiniciando"
},
"status": {
"loading": "Cargando configuración...",
"loadError": "No se pudo cargar la configuración",
"unsaved": "Hay cambios sin guardar.",
"loading": "Cargando ajustes...",
"loadError": "No se pudieron cargar los ajustes",
"unsaved": "Cambios sin guardar.",
"upToDate": "Actualizado.",
"savedRestart": "Guardado. Reinicia nanobot para aplicar.",
"restartAfterSaving": "Guarda los cambios y reinicia cuando estés listo.",
"savedRestartApply": "Guardado. Reinicia cuando estés listo.",
"imageProviderRestart": "Cambios del proveedor de imágenes guardados. Reinicia cuando estés listo.",
"hostRestartAfterSaving": "Guarda los cambios y nanobot reiniciará su motor.",
"hostRestartPending": "Guardado. Reiniciando el motor cuando esté listo.",
"hostApiUnavailable": "Host actions are only available inside the native app.",
"logsOpened": "Opened logs folder.",
"logsOpenFailed": "Could not open logs folder.",
"diagnosticsExported": "Diagnostics exported to {{path}}.",
"diagnosticsExportFailed": "Could not export diagnostics."
"restartAfterSaving": "Guarda los cambios y reinicia cuando puedas.",
"savedRestartApply": "Guardado. Reinicia cuando puedas.",
"imageProviderRestart": "Cambios del proveedor de imagen guardados. Reinicia cuando puedas.",
"hostRestartAfterSaving": "Al guardar, nanobot reiniciará su motor.",
"hostRestartPending": "Guardado. El motor se reiniciará cuando esté listo.",
"hostApiUnavailable": "Las acciones del host solo están disponibles en la app nativa.",
"logsOpened": "Carpeta de registros abierta.",
"logsOpenFailed": "No se pudo abrir la carpeta de registros.",
"diagnosticsExported": "Diagnóstico exportado a {{path}}.",
"diagnosticsExportFailed": "No se pudo exportar el diagnóstico."
},
"actions": {
"save": "Guardar",
@@ -224,8 +224,8 @@
"cancel": "Cancelar",
"open": "Abrir",
"export": "Exportar",
"opening": "Opening...",
"exporting": "Exporting..."
"opening": "Abriendo...",
"exporting": "Exportando..."
},
"byok": {
"description": "Usa tus propias claves de proveedor. Nanobot lee estos valores desde la configuración actual, y solo los proveedores configurados se pueden elegir en General.",
@@ -250,7 +250,7 @@
"tabs": {
"ariaLabel": "Tipo de credencial BYOK",
"llm": "LLM",
"webSearch": "Web Search"
"webSearch": "Búsqueda web"
},
"webSearch": {
"provider": "Proveedor de búsqueda",
@@ -270,44 +270,44 @@
}
},
"overview": {
"model": "Current model",
"providers": "Providers",
"configuredCount": "{{count}} configured",
"totalProviders": "{{count}} available",
"webSearch": "Web search",
"model": "Modelo actual",
"providers": "Proveedores",
"configuredCount": "{{count}} configurados",
"totalProviders": "{{count}} disponibles",
"webSearch": "Búsqueda web",
"imageGeneration": "Generación de imágenes",
"workspace": "Workspace"
"workspace": "Espacio de trabajo"
},
"providers": {
"searchPlaceholder": "Search providers",
"noMatches": "No providers match this search.",
"searchPlaceholder": "Buscar proveedores",
"noMatches": "Ningún proveedor coincide con esta búsqueda.",
"saveProvider": "Guardar proveedor"
},
"image": {
"selectProvider": "Seleccionar proveedor",
"selectAspect": "Seleccionar relación",
"selectAspect": "Seleccionar proporción",
"selectSize": "Seleccionar tamaño",
"configureProvider": "Configurar proveedor",
"missingCredential": "Configura este proveedor antes de activar la generación de imágenes."
},
"models": {
"selectModel": "Seleccionar modelo",
"addConfiguration": "Añadir configuración",
"addConfiguration": "Agregar configuración",
"newConfiguration": "Nueva configuración de modelo",
"newConfigurationHelp": "Guarda un proveedor y un modelo como una opción de un clic.",
"newConfigurationHelp": "Guarda un proveedor y modelo como opción de un clic.",
"configurationName": "Nombre de configuración",
"configurationNameHelp": "Cambia el nombre de esta configuración de modelo guardada.",
"configurationNameHelp": "Renombra esta configuración de modelo guardada.",
"configurationNamePlaceholder": "Escritura rápida",
"searchModels": "Buscar o escribir ID de modelo",
"useCustomModel": "Usar",
"loadingModels": "Cargando modelos...",
"searchCatalog": "Busca en el catálogo del proveedor para elegir un modelo.",
"searchCatalog": "Busca el catálogo del proveedor para elegir un modelo.",
"modelsAvailable": "disponibles",
"noModelResults": "No hay modelos coincidentes.",
"loadFailed": "Lista de modelos no disponible.",
"unsupportedModelList": "Escribe manualmente un ID de modelo.",
"unsupportedModelList": "Escribe un ID de modelo manualmente.",
"providerNotConfigured": "Configura este proveedor antes de cargar modelos.",
"autoProviderCustomOnly": "El modo de proveedor automático usa ID de modelo personalizados."
"autoProviderCustomOnly": "El modo de proveedor automático usa IDs de modelo personalizados."
},
"timezone": {
"select": "Seleccionar zona horaria",
@@ -316,7 +316,7 @@
},
"cliApps": {
"allCategories": "Todas las categorías",
"availableCount": "{{count}} apps",
"availableCount": "{{count}} aplicaciones",
"installedCount": "{{count}} instaladas",
"summary": "{{installed}} de {{total}} CLIs instaladas",
"filterAll": "Todas",
@@ -402,7 +402,7 @@
"thirdPartyBrands": "Los nombres, logotipos y marcas de productos pertenecen a sus respectivos propietarios. Su uso es solo identificativo y no implica respaldo."
},
"apps": {
"description": "Añade CLI de apps y servicios MCP que nanobot puede usar desde el chat.",
"description": "Agrega CLI de apps y servicios MCP que nanobot puede usar desde el chat.",
"cliLabel": "CLI",
"mcpLabel": "MCP",
"filterAll": "Todo",
@@ -416,17 +416,17 @@
"empty": "Ninguna app coincide con este filtro."
},
"oauth": {
"authentication": "OAuth authentication",
"signIn": "Sign in",
"signingIn": "Signing in...",
"signInAgain": "Sign in again",
"signOut": "Sign out",
"signedInAs": "Signed in as {{account}}",
"signInHelp": "Sign in from this device; no API key is stored in config.",
"signInRequired": "Sign in required",
"signInBeforeSaving": "Sign in before saving this OAuth provider as the active model provider.",
"signedIn": "Signed in",
"notSignedIn": "Not signed in"
"authentication": "Autenticación OAuth",
"signIn": "Iniciar sesión",
"signingIn": "Iniciando sesión...",
"signInAgain": "Iniciar sesión de nuevo",
"signOut": "Cerrar sesión",
"signedInAs": "Sesión iniciada como {{account}}",
"signInHelp": "Inicia sesión desde este dispositivo; no se guarda API key en config.",
"signInRequired": "Inicio de sesión requerido",
"signInBeforeSaving": "Inicia sesión antes de guardar este proveedor OAuth como proveedor activo.",
"signedIn": "Sesión iniciada",
"notSignedIn": "Sin sesión"
}
},
"chat": {