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
+134 -134
View File
@@ -57,22 +57,22 @@
"apps": "Ứng dụng"
},
"settings": {
"backToChat": "Quay lại trò chuyện",
"backToChat": "Quay lại chat",
"sidebar": {
"title": "Cài đặt",
"ariaLabel": "Các mục cài đặt"
"ariaLabel": "Mục cài đặt"
},
"nav": {
"general": "Chung",
"byok": "BYOK",
"overview": "Overview",
"appearance": "Appearance",
"models": "Models",
"providers": "Providers",
"image": "Image",
"browser": "Web",
"overview": "Tổng quan",
"appearance": "Giao diện",
"models": "Mô hình",
"providers": "Nhà cung cấp",
"image": "Hình ảnh",
"browser": "Trang web",
"runtime": "Hệ thống",
"advanced": "Security",
"advanced": "Bảo mật",
"cliApps": "Ứng dụng CLI",
"mcp": "MCP",
"apps": "Ứng dụng"
@@ -81,122 +81,122 @@
"interface": "Giao diện",
"ai": "AI",
"system": "Hệ thống",
"status": "Status",
"localPreferences": "Local preferences",
"presets": "Presets",
"imageGeneration": "Tạo ảnh",
"status": "Trạng thái",
"localPreferences": "Tùy chọn cục bộ",
"presets": "Preset",
"imageGeneration": "Tạo hình ảnh",
"imageDefaults": "Mặc định",
"webSearch": "Web search",
"webBehavior": "Behavior",
"identity": "Identity",
"webuiSafety": "Web safety",
"webSearch": "Tìm kiếm web",
"webBehavior": "Hành vi",
"identity": "Danh tính",
"webuiSafety": "An toàn WebUI",
"capabilities": "Khả năng",
"cliApps": "Ứng dụng CLI",
"mcp": "Dịch vụ MCP",
"apps": "Ứng dụng",
"nativeHost": "Native host",
"hostSafety": "App safety"
"nativeHost": "Host gốc",
"hostSafety": "An toàn ứng dụng"
},
"rows": {
"theme": "Giao diện",
"theme": "Chủ đề",
"language": "Ngôn ngữ",
"provider": "Nhà cung cấp",
"model": "Mô hình",
"restart": "Khởi động lại nanobot",
"configPath": "Đường dẫn cấu hình",
"activePreset": "Active preset",
"gateway": "Gateway",
"restartState": "Restart state",
"pendingChanges": "Thay đổi đang chờ",
"selectedPreset": "Selected preset",
"presetModel": "Preset model",
"density": "Density",
"activityMode": "Activity detail",
"codeWrap": "Code wrapping",
"maxResults": "Max results",
"timeout": "Timeout",
"jinaReader": "Jina reader",
"imageGeneration": "Tạo ảnh",
"imageProvider": "Nhà cung cấp ảnh",
"activePreset": "Preset đang dùng",
"gateway": "Cổng",
"restartState": "Trạng thái khởi động lại",
"pendingChanges": "Thay đổi chờ áp dụng",
"selectedPreset": "Preset đã chọn",
"presetModel": "Mô hình preset",
"density": "Mật độ",
"activityMode": "Chi tiết hoạt động",
"codeWrap": "Xuống dòng mã",
"maxResults": "Kết quả tối đa",
"timeout": "Thời gian chờ",
"jinaReader": "Trình đọc Jina",
"imageGeneration": "Tạo hình ảnh",
"imageProvider": "Nhà cung cấp hình ảnh",
"imageProviderStatus": "Trạng thái nhà cung cấp",
"imageProviderBase": "Cơ sở nhà cung cấp",
"imageModel": "Mô hình ảnh",
"imageProviderBase": "Địa chỉ nhà cung cấp",
"imageModel": "Mô hình hình ảnh",
"defaultAspectRatio": "Tỷ lệ mặc định",
"defaultImageSize": "Kích thước mặc định",
"maxImagesPerTurn": "Số ảnh tối đa mỗi lượt",
"maxImagesPerTurn": "nh tối đa mỗi lượt",
"imageSaveDir": "Thư mục lưu",
"botName": "Bot name",
"botIcon": "Bot icon",
"timezone": "Timezone",
"botName": "Tên bot",
"botIcon": "Biểu tượng bot",
"timezone": "Múi giờ",
"workspacePath": "Workspace mặc định",
"localServiceAccess": "Local services",
"webuiDefaultAccess": "Default access",
"localServiceAccess": "Dịch vụ cục bộ",
"webuiDefaultAccess": "Quyền mặc định",
"currentModel": "Cấu hình hiện tại",
"brandLogos": "Logo thương hiệu",
"cliAppsCatalog": "Danh mục ứng dụng CLI",
"cliAppsFilter": "Bộ lọc ứng dụng CLI",
"engine": "Engine",
"cliAppsCatalog": "Danh mục",
"cliAppsFilter": "Bộ lọc",
"engine": "Bộ máy",
"logs": "Nhật ký",
"diagnostics": "Chẩn đoán",
"contextWindow": "Context window"
"contextWindow": "Cửa sổ ngữ cảnh"
},
"help": {
"theme": "Chuyển giữa giao diện sáng và tối.",
"language": "Chọn ngôn ngữ dùng trong WebUI.",
"provider": "Chọn nhà cung cấp cho các yêu cầu mô hình mới.",
"model": "Đặt tên mô hình mặc định mà nanobot sử dụng.",
"configPath": "Tệp cấu hình gateway hiện đang dùng.",
"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": "Hiển thị generate_image trong chat khi có nhà cung cấp ảnh đã cấu hình.",
"imageProvider": "Chọn nhà cung cấp registry được generate_image sử dụng.",
"imageProviderStatus": "Tạo ảnh dùng lại thông tin xác thực nhà cung cấp từ Providers.",
"imageModel": "Tên mô hình gửi tới nhà cung cấp ảnh đã chọn.",
"defaultAspectRatio": "Được dùng khi prompt không chọn tỷ lệ khung hình.",
"defaultImageSize": "Gợi ý kích thước gửi tới các nhà cung cấp hỗ trợ.",
"provider": "Selecciona el proveedor para nuevas solicitudes de modelo.",
"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": "Chuyển sang Default để chỉnh sửa mô hình và nhà cung cấp từ WebUI.",
"density": "Chỉ lưu trong trình duyệt này.",
"activityMode": "Chọn mức chi tiết hoạt động agent hiển thị mặc định.",
"codeWrap": "Giữ các dòng mã dài dễ đọc trên màn hình nhỏ.",
"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 proporción.",
"defaultImageSize": "Gợi ý kích thước gửi tới nhà cung cấp hỗ trợ.",
"maxImagesPerTurn": "Giới hạn trên cho một yêu cầu generate_image.",
"botName": "Hiển thị ở nơi nanobot dùng tên hiển thị.",
"botIcon": "Emoji hoặc văn bản ngắn hiển thị cùng tên bot.",
"timezone": "Dùng cho lịch hẹn và câu trả lời có yếu tố thời gian.",
"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": "Chọn cấu hình mô hình nanobot dùng cho các câu trả lời mới.",
"selectedModelProvider": "Được đặt bởi mô hình đã chọn.",
"selectedModelValue": "Được đặt bởi mô hình đã chọn.",
"brandLogos": "Logo được tải từ tên miền thương hiệu, có biểu tượng cục bộ làm dự phòng.",
"cliAppsCatalog": "Duyệt các CLI ứng dụng mà nanobot có thể chạy cục bộ.",
"cliAppsFilter": "Tìm theo ứng dụng, danh mục hoặc khả năng.",
"logs": "Mở thư mục nhật ký native engine.",
"diagnostics": "Xuất báo cáo runtime nhỏ để hỗ trợ.",
"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."
"botName": "Se muestra donde nanobot usa un nombre visible.",
"botIcon": "Emoji o texto corto junto al nombre del bot.",
"timezone": "Se usa para horarios y respuestas con conciencia temporal.",
"localServiceAccess": "Cho phép lệnh shell Full Access truy cập dịch vụ localhost.",
"webuiDefaultAccess": "Dùng cho chat web không có quyền riêng theo dự án.",
"securityManagedControls": "Las capturas web siempre protegen servicios locales, privados y metadata. La seguridad de canales core se gestiona en config.json.",
"currentModel": "Dùng cho các phản hồi mới.",
"selectedModelProvider": "Definido por el modelo seleccionado.",
"selectedModelValue": "Definido por el modelo seleccionado.",
"brandLogos": "Hiển thị logo nhà cung cấp bên thứ ba và CLI trong Cài đặt.",
"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 nativo.",
"diagnostics": "Exporta un pequeño informe de runtime para soporte.",
"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": "Chọn ngân sách ngữ cảnh mặc định cho cấu hình mô hình này."
},
"values": {
"light": "Sáng",
"dark": "Tối",
"notAvailable": "Không khả dụng",
"enabled": "Enabled",
"disabled": "Disabled",
"restartPending": "Đang chờ khởi động lại",
"enabled": "Đã bật",
"disabled": "Đã tắt",
"restartPending": "Chờ khởi động lại",
"ready": "Sẵn sàng",
"comfortable": "Comfortable",
"compact": "Compact",
"auto": "Auto",
"expanded": "Expanded",
"on": "On",
"off": "Off",
"defaultPermission": "Default Permission",
"fullAccess": "Full Access",
"configured": "Configured",
"notConfigured": "Not configured",
"comfortable": "Thoải mái",
"compact": "Gọn",
"auto": "Tự động",
"expanded": "Mở rộng",
"on": "Bật",
"off": "Tắt",
"defaultPermission": "Quyền mặc định",
"fullAccess": "Toàn quyền",
"configured": "Đã cấu hình",
"notConfigured": "Chưa cấu hình",
"pending": "Đang chờ",
"restartingEngine": "Đang khởi động lại"
},
@@ -205,17 +205,17 @@
"loadError": "Không thể tải cài đặt",
"unsaved": "Có thay đổi chưa lưu.",
"upToDate": "Đã cập nhật.",
"savedRestart": "Đã lưu. Khởi động lại nanobot để áp dụng.",
"restartAfterSaving": "Lưu thay đổi, rồi khởi động lại khi sẵn sàng.",
"savedRestartApply": "Đã lưu. Khởi động lại khi sẵn sàng.",
"imageProviderRestart": "Đã lưu thay đổi nhà cung cấp ảnh. Khởi động lại khi sẵn sàng.",
"hostRestartAfterSaving": "Lưu thay đổi và nanobot sẽ khởi động lại engine.",
"hostRestartPending": "Đã lưu. Sẽ khởi động lại engine khi sẵn sàng.",
"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."
"savedRestart": "Guardado. Reinicia nanobot para aplicar.",
"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": "Lưu",
@@ -224,8 +224,8 @@
"cancel": "Hủy",
"open": "Mở",
"export": "Xuất",
"opening": "Opening...",
"exporting": "Exporting..."
"opening": "Đang mở...",
"exporting": "Đang xuất..."
},
"byok": {
"description": "Dùng key provider của riêng bạn. Nanobot đọc các giá trị này từ config hiện tại, và chỉ provider đã cấu hình mới có thể chọn trong Chung.",
@@ -250,10 +250,10 @@
"tabs": {
"ariaLabel": "Loại thông tin xác thực BYOK",
"llm": "LLM",
"webSearch": "Web Search"
"webSearch": "Tìm kiếm web"
},
"webSearch": {
"provider": "Search provider",
"provider": "Nhà cung cấp tìm kiếm",
"providerHelp": "Chọn backend mà công cụ web search sẽ dùng.",
"selectProvider": "Chọn provider",
"credentials": "Thông tin xác thực",
@@ -270,17 +270,17 @@
}
},
"overview": {
"model": "Current model",
"providers": "Providers",
"configuredCount": "{{count}} configured",
"totalProviders": "{{count}} available",
"webSearch": "Web search",
"imageGeneration": "Tạo ảnh",
"workspace": "Workspace"
"model": "Mô hình hiện tại",
"providers": "Nhà cung cấp",
"configuredCount": "{{count}} đã cấu hình",
"totalProviders": "{{count}} khả dụng",
"webSearch": "Tìm kiếm web",
"imageGeneration": "Tạo hình ảnh",
"workspace": "Không gian làm việc"
},
"providers": {
"searchPlaceholder": "Search providers",
"noMatches": "No providers match this search.",
"searchPlaceholder": "Tìm nhà cung cấp",
"noMatches": "Không có nhà cung cấp phù hợp.",
"saveProvider": "Lưu nhà cung cấp"
},
"image": {
@@ -288,17 +288,17 @@
"selectAspect": "Chọn tỷ lệ",
"selectSize": "Chọn kích thước",
"configureProvider": "Cấu hình nhà cung cấp",
"missingCredential": "Cấu hình nhà cung cấp này trước khi bật tạo ảnh."
"missingCredential": "Configura este proveedor antes de activar la generación de imágenes."
},
"models": {
"selectModel": "Chọn mô hình",
"addConfiguration": "Thêm cấu hình",
"newConfiguration": "Cấu hình mô hình mới",
"newConfigurationHelp": "Lưu nhà cung cấp và mô hình thành một lựa chọn một lần nhấp.",
"newConfigurationHelp": "Lưu nhà cung cấp và mô hình thành một lựa chọn nhanh.",
"configurationName": "Tên cấu hình",
"configurationNameHelp": "Đổi tên cấu hình mô hình đã lưu này.",
"configurationNamePlaceholder": "Viết nhanh",
"searchModels": "Tìm hoặc nhập ID mô hình",
"searchModels": "Tìm kiếm hoặc nhập ID mô hình",
"useCustomModel": "Dùng",
"loadingModels": "Đang tải mô hình...",
"searchCatalog": "Tìm trong danh mục nhà cung cấp để chọn mô hình.",
@@ -306,7 +306,7 @@
"noModelResults": "Không có mô hình phù hợp.",
"loadFailed": "Không tải được danh sách mô hình.",
"unsupportedModelList": "Nhập ID mô hình thủ công.",
"providerNotConfigured": "Cấu hình nhà cung cấp này trước khi tải mô hình.",
"providerNotConfigured": "Hãy cấu hình nhà cung cấp này trước khi tải mô hình.",
"autoProviderCustomOnly": "Chế độ nhà cung cấp tự động dùng ID mô hình tùy chỉnh."
},
"timezone": {
@@ -402,7 +402,7 @@
"thirdPartyBrands": "Tên sản phẩm, logo và thương hiệu thuộc về chủ sở hữu tương ứng. Việc sử dụng chỉ nhằm nhận diện và không ngụ ý được xác nhận."
},
"apps": {
"description": "Thêm CLI ứng dụng và dịch vụ MCP để nanobot dùng trong trò chuyện.",
"description": "Thêm CLI ứng dụng và dịch vụ MCP nanobot có thể dùng trong chat.",
"cliLabel": "CLI",
"mcpLabel": "MCP",
"filterAll": "Tất cả",
@@ -413,20 +413,20 @@
"searchPlaceholder": "Tìm ứng dụng",
"featured": "Nổi bật",
"loading": "Đang tải ứng dụng...",
"empty": "Không có ứng dụng nào khớp với bộ lọc này."
"empty": "Không có ứng dụng phù hợp."
},
"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": "Xác thực OAuth",
"signIn": "Đăng nhập",
"signingIn": "Đang đăng nhập...",
"signInAgain": "Đăng nhập lại",
"signOut": "Đăng xuất",
"signedInAs": "Đã đăng nhập bằng {{account}}",
"signInHelp": "Inicia sesión desde este dispositivo; no se guarda API key en config.",
"signInRequired": "Cần đăng nhập",
"signInBeforeSaving": "Inicia sesión antes de guardar este proveedor OAuth como proveedor activo.",
"signedIn": "Đã đăng nhập",
"notSignedIn": "Chưa đăng nhập"
}
},
"chat": {