From e74441276093c52f6af25bffeea4df06acd4e60b Mon Sep 17 00:00:00 2001 From: nguyenha935 Date: Mon, 20 Jul 2026 08:31:04 +0700 Subject: [PATCH] fix(i18n): complete Vietnamese dashboard localization and runtime fixes (#7493) * fix(i18n): complete Vietnamese locale * fix(i18n): localize remaining Vietnamese dashboard surfaces * fix(i18n): localize CLI catalog and shared navigation * fix(i18n): repair dashboard routes and shared provider UI * chore(lint): prune resolved CLI guide suppressions * fix(i18n): finish Vietnamese dashboard runtime copy * fix(i18n): complete Vietnamese dashboard localization * fix(i18n): align Vietnamese locale key order * fix(i18n): localize remaining production surfaces * fix(env): write repaired settings to data directory * fix(i18n): sync Vietnamese locale with release * fix(i18n): keep Vietnamese parity order-independent * fix(i18n): address locale review regressions * feat(i18n): sync complete UI translations * fix(i18n): sync locale keys after rebase * docs: sync release metadata and environment references * chore(quality): rebaseline localized UI files * fix(quality): repair release-base regressions * chore(test): sync mutation coverage inputs * fix(quality): keep localized UI within complexity ratchet * fix(typecheck): repair localized dashboard regressions * fix(test): clear locale and dashboard CI failures * chore(ci): retry interrupted DAST run * fix(ci): keep DAST smoke within probe budget * fix(quality): drop scope-creep test/baseline changes from vi-locale PR The merge-conflict resolution in this Vietnamese i18n PR accidentally carried over reformatting-only changes to tests/unit/db-core-init.test.ts (Prettier layout + a fixture column) that have nothing to do with localization. Revert that file to the release/v3.8.49 version and drop the two rebaseline entries this created in file-size-baseline.json, restoring the db-core-init.test.ts ceiling to 877. The legitimate i18n rebaseline entry (_rebaseline_2026_07_19_pr7493_i18n) is untouched. Co-authored-by: Diego Rodrigues de Sa e Souza * fix(i18n): rescope PR to Vietnamese translation quality only The bulk-filled en.json in this branch carried +2219 phantom keys from a stale base, breaking key parity for every other locale, and the code changes (EndpointPageClient.tsx and others) broke existing dashboard contract tests. Everything outside src/i18n/messages/vi.json is reverted to release/v3.8.49; only the Vietnamese translation improvements remain (659 previously __MISSING__ keys filled, 2573 English-fallback keys translated, 2179 over-translated technical literals like "POST /a2a" corrected back to their original form). Reconciled the vi.json keyset against the current release tip (English UI strings added by merged PRs since this branch was opened) using the same plain-English-fallback convention already used elsewhere in the file, and added a regression test asserting Vietnamese key parity with English, ICU placeholder parity, and no missing/empty translations. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: nguyenha935 <208228297+nguyenha935@users.noreply.github.com> Co-authored-by: Diego Rodrigues de Sa e Souza Co-authored-by: Diego Rodrigues de Sa e Souza Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --- .../fixes/7493-vietnamese-locale-quality.md | 1 + src/i18n/messages/vi.json | 12574 +++++++++------- tests/unit/i18n-vi-completeness.test.ts | 83 + 3 files changed, 7227 insertions(+), 5431 deletions(-) create mode 100644 changelog.d/fixes/7493-vietnamese-locale-quality.md create mode 100644 tests/unit/i18n-vi-completeness.test.ts diff --git a/changelog.d/fixes/7493-vietnamese-locale-quality.md b/changelog.d/fixes/7493-vietnamese-locale-quality.md new file mode 100644 index 0000000000..984f08c9e6 --- /dev/null +++ b/changelog.d/fixes/7493-vietnamese-locale-quality.md @@ -0,0 +1 @@ +- fix(i18n): replace machine-bulk-filled Vietnamese UI strings with human-quality translations — 5411 values improved, technical literals (RPC methods, endpoints) no longer over-translated (#7493) diff --git a/src/i18n/messages/vi.json b/src/i18n/messages/vi.json index aadc18f7f1..3518e52fda 100644 --- a/src/i18n/messages/vi.json +++ b/src/i18n/messages/vi.json @@ -5,7 +5,7 @@ "delete": "Xóa", "loading": "Đang tải...", "error": "Đã xảy ra lỗi", - "success": "thành công", + "success": "Thành công", "confirm": "Bạn có chắc không?", "refresh": "Làm mới", "close": "Đóng", @@ -22,28 +22,28 @@ "disabled": "Đã tắt", "active": "Đang hoạt động", "inactive": "Không hoạt động", - "noData": "Không có sẵn dữ liệu", - "nothingHere": "Nothing here yet", + "noData": "Không có dữ liệu", + "nothingHere": "Chưa có gì ở đây", "configure": "Cấu hình", "manage": "Quản lý", "name": "Tên", - "actions": "hành động", + "actions": "Hành động", "status": "Trạng thái", - "type": "loại", - "model": "người mẫu", + "type": "Loại", + "model": "Mô hình", "models": "mô hình", - "provider": "nhà cung cấp", + "provider": "Nhà cung cấp", "account": "Tài khoản", - "time": "thời gian", + "time": "Thời gian", "details": "Chi tiết", "created": "Đã tạo", - "lastUsed": "Last Refreshed", + "lastUsed": "Lần làm mới gần nhất", "loadMore": "Tải thêm", "noResults": "Không tìm thấy kết quả nào", "reloadPage": "Tải lại trang", "connected": "Đã kết nối", "disconnected": "Đã ngắt kết nối", - "notConfigured": "Chưa được định cấu hình", + "notConfigured": "Chưa được cấu hình", "testConnection": "Kiểm tra kết nối", "enable": "Kích hoạt", "disable": "Vô hiệu hóa", @@ -51,626 +51,626 @@ "newest": "Mới nhất", "oldest": "Cũ nhất", "all": "Tất cả", - "none": "không có", + "none": "Không có", "yes": "Có", "no": "Không", - "on": "__MISSING__:ON", - "off": "__MISSING__:OFF", + "on": "BẬT", + "off": "TẮT", "warning": "Cảnh báo", "note": "Lưu ý", - "free": "miễn phí", + "free": "Miễn phí", "skipToContent": "Chuyển đến nội dung", - "maintenanceServerIssues": "Server is experiencing issues. Some features may be unavailable.", - "maintenanceServerUnreachable": "Server is unreachable. Reconnecting...", + "maintenanceServerIssues": "Máy chủ đang gặp sự cố. Một số tính năng có thể không khả dụng.", + "maintenanceServerUnreachable": "Không thể kết nối đến máy chủ. Đang kết nối lại...", "accept": "Chấp nhận", "accountId": "ID tài khoản", "alias": "Bí danh", "apiKeyId": "ID khóa API", "apiKeyName": "Tên khóa API", - "apiKeySecret": "Bí mật khóa API", + "apiKeySecret": "Khóa bí mật API", "authorization": "Ủy quyền", "content-type": "Loại nội dung", "content-length": "Độ dài nội dung", - "cookie": "bánh quy", - "file": "tập tin", + "cookie": "Cookie", + "file": "Tập tin", "host": "Máy chủ", "id": "ID", - "import": "Nhập khẩu", - "limit": "giới hạn", - "offset": "Bù đắp", + "import": "Nhập", + "limit": "Giới hạn", + "offset": "Offset", "open": "Mở", - "origin": "Xuất xứ", - "promptTokens": "Mã thông báo nhắc nhở", - "completionTokens": "Mã thông báo hoàn thành", + "origin": "Origin", + "promptTokens": "Token của prompt", + "completionTokens": "Token hoàn thành", "totalTokens": "Tổng số token", "rawModel": "Mô hình thô", "scope": "Phạm vi", - "skill": "kỹ năng", + "skill": "Kỹ năng", "sortBy": "Sắp xếp theo", - "sortOrder": "Sắp xếp thứ tự", + "sortOrder": "Thứ tự sắp xếp", "tab": "Thẻ", - "text": "văn bản", + "text": "Văn bản", "textarea": "Vùng văn bản", "tool": "Công cụ", - "toolId": "Mã công cụ", + "toolId": "ID công cụ", "web": "Web", "whereUsed": "Nơi sử dụng", "whitelist": "Danh sách trắng", "blacklist": "Danh sách đen", - "resolve": "giải quyết", - "force": "Lực lượng", - "base64url": "URL Base64", - "hex": "lục giác", + "resolve": "Giải quyết", + "force": "Buộc", + "base64url": "Base64 URL", + "hex": "Hex", "range": "Phạm vi", - "component": "thành phần", + "component": "Thành phần", "redirect_uri": "URI chuyển hướng", - "idempotency-key": "Chìa khóa bình đẳng", + "idempotency-key": "Khóa Idempotency", "error_description": "Mô tả lỗi", "code": "Mã", "compatible": "Tương thích", - "chat-completions": "Hoàn thành cuộc trò chuyện", + "chat-completions": "Chat Completions", "oauth": "OAuth", - "auth_token": "Mã thông báo xác thực", - "crypto": "tiền điện tử", + "auth_token": "Token xác thực", + "crypto": "Mật mã", "hours": "Giờ", "selfsigned": "Tự ký", "proxy_id": "ID proxy", "proxyId": "ID proxy", "connectionId": "ID kết nối", - "resolveConnectionId": "Giải quyết ID kết nối", - "resolve_connection_id": "Giải quyết ID kết nối", + "resolveConnectionId": "Phân giải ID kết nối", + "resolve_connection_id": "Phân giải ID kết nối", "scope_id": "ID phạm vi", "scopeId": "ID phạm vi", - "jwtSecret": "Bí mật JWT", - "keytar": "Bàn phím", - "better-sqlite3": "tốt hơn-sqlite3", - "undici": "undic", - "builder-id": "ID người xây dựng", + "jwtSecret": "Khóa bí mật JWT", + "keytar": "Keytar", + "better-sqlite3": "better-sqlite3", + "undici": "undici", + "builder-id": "Builder ID", "musicDesc": "Mô tả âm nhạc", - "musicGeneration": "Thế hệ âm nhạc", + "musicGeneration": "Tạo nhạc", "idc": "IDC", "cloud-status-changed": "Trạng thái đám mây đã thay đổi", - "where_used": "Nơi sử dụng", + "where_used": "Được sử dụng ở đâu", "windowMs": "Cửa sổ (ms)", "social-github": "GitHub", "social-google": "Google", - "TOOL_ALLOWLIST": "Danh sách cho phép của công cụ", - "TOOL_DENYLIST": "Danh sách từ chối công cụ", + "TOOL_ALLOWLIST": "Danh sách công cụ được phép", + "TOOL_DENYLIST": "Danh sách công cụ bị chặn", "Failed to save pricing": "Không lưu được giá", "Failed to reset pricing": "Không thể đặt lại giá", "apikey": "Khóa API", "http": "HTTP", - "goToDashboard": "Go to Dashboard", - "checkSystemStatus": "Check System Status", - "selectModel": "Select Model", - "combos": "Combos", - "noModelsFound": "No models found", - "clear": "Clear", - "done": "Done", - "errorOccurred": "Error Occurred", - "comboDeleted": "Combo Deleted", - "hide": "Hide", - "creating": "Creating", - "comboCreated": "Combo Created", - "swapFormats": "Swap Formats", - "daysAgo": "Days Ago", - "retries": "Retries", - "errorDuringRestore": "Error During Restore", - "eventsAppearHint": "Events Appear Hint", - "noLockouts": "No Lockouts", - "webSearchDesc": "Web Search Desc", - "audioProvidersHeading": "Audio Providers Heading", - "cloudAgentProviders": "Nhà cung cấp đại lý đám mây", - "minutesAgo": "Minutes Ago", + "goToDashboard": "Đi tới bảng điều khiển", + "checkSystemStatus": "Kiểm tra trạng thái hệ thống", + "selectModel": "Chọn mô hình", + "combos": "Combo", + "noModelsFound": "Không tìm thấy mô hình nào", + "clear": "Xóa", + "done": "Xong", + "errorOccurred": "Đã xảy ra lỗi", + "comboDeleted": "Đã xóa combo", + "hide": "Ẩn", + "creating": "Đang tạo", + "comboCreated": "Đã tạo combo", + "swapFormats": "Hoán đổi định dạng", + "daysAgo": "Ngày trước đây", + "retries": "Số lần thử lại", + "errorDuringRestore": "Lỗi trong khi khôi phục", + "eventsAppearHint": "Gợi ý: sự kiện sẽ xuất hiện ở đây", + "noLockouts": "Không có tình trạng bị khóa", + "webSearchDesc": "Mô tả Tìm kiếm Web", + "audioProvidersHeading": "Tiêu đề Nhà cung cấp Âm thanh", + "cloudAgentProviders": "Nhà cung cấp tác nhân đám mây", + "minutesAgo": "Phút trước", "a": "A", - "liveAutoRefreshing": "Live Auto Refreshing", - "webSearch": "Web Search", - "anthropicPrefixPlaceholder": "Anthropic Prefix Placeholder", - "addModelToCombo": "Add Model To Combo", - "failedToLoad": "Failed To Load", - "categoryMedia": "Category Media", - "enableCloud": "Enable Cloud", - "expirationBannerExpiringSoon": "Expiration Banner Expiring Soon", - "retry": "Retry", + "liveAutoRefreshing": "Đang tự động làm mới theo thời gian thực", + "webSearch": "Tìm kiếm trên web", + "anthropicPrefixPlaceholder": "Chỗ giữ tiền tố Anthropic", + "addModelToCombo": "Thêm mô hình vào combo", + "failedToLoad": "Không thể tải", + "categoryMedia": "Danh mục đa phương tiện", + "enableCloud": "Bật đám mây", + "expirationBannerExpiringSoon": "Thông báo sắp hết hạn", + "retry": "Thử lại", "embeddings": "Embeddings", - "errorCount": "Error Count", - "backupReasonManual": "Backup Reason Manual", - "safeSearchModerate": "Safe Search Moderate", - "activeLimiters": "Active Limiters", - "a2aCardTitle": "A2A Card Title", - "cloudWorkerUnreachable": "Cloud Worker Unreachable", - "testFailed": "Test Failed", - "compatibleBaseUrlHint": "Compatible Base Url Hint", - "usageTracking": "Usage Tracking", - "disableCloudTitle": "Disable Cloud Title", - "noConnections": "No Connections", - "providerHealth": "Provider Health", - "confirmDbImport": "Confirm Db Import", - "notAvailableSymbol": "Not Available Symbol", - "backupsAvailable": "Backups Available", - "providerAuto": "Provider Auto", - "newProviderNamePlaceholder": "New Provider Name Placeholder", - "a2aQuickStartStep2": "A2A Quick Start Step2", - "ok": "Ok", - "available": "Available", - "noBackupYet": "No Backup Yet", - "more": "More", - "noCompatibleYet": "No Compatible Yet", - "multiProvider": "Multi Provider", - "repairEnvHint": "Repair Env Hint", - "disablingCloud": "Disabling Cloud", - "testBench": "Test Bench", - "valid": "Valid", - "cloudBenefitShare": "Cloud Benefit Share", - "mcpCardTitle": "Mcp Card Title", - "disableConfirm": "Disable Confirm", - "filters": "Filters", - "expirationBannerExpiredDesc": "Expiration Banner Expired Desc", - "saveComboDefaults": "Save Combo Defaults", - "cloudConnectedVerified": "Cloud Connected Verified", - "uptime": "Uptime", - "compatibleProdPlaceholder": "Compatible Prod Placeholder", - "fallbackChainsTitle": "Fallback Chains Title", - "oauthLabel": "Oauth Label", - "a2aCardDescription": "A2A Card Description", - "okShort": "Ok Short", - "maintenance": "Maintenance", - "formatConverter": "Format Converter", - "zedImportNetworkError": "Zed Import Network Error", - "apiKeyLabel": "Api Key Label", - "noModelsForProvider": "No Models For Provider", - "mcpCardDescription": "Mcp Card Description", - "apiTypeLabel": "Api Type Label", - "configuredProvidersLabel": "Configured Providers Label", - "maxRetriesLabel": "Max Retries Label", - "title": "Title", - "output": "Output", - "prefixHint": "Prefix Hint", - "skipWizard": "Skip Wizard", - "failedCount": "Failed Count", - "confirmDbImportDesc": "Confirm Db Import Desc", - "entries": "Entries", - "until": "Until", - "disableCombo": "Disable Combo", - "liveMonitorDescriptionPrefix": "Live Monitor Description Prefix", - "runningCount": "Running Count", - "noActiveConnectionsInGroup": "No Active Connections In Group", - "savedSuccessfully": "Saved Successfully", - "systemStorage": "System Storage", - "videoDesc": "Video Desc", - "maxResults": "Max Results", - "timeRangeMonth": "Time Range Month", - "testSummary": "Test Summary", - "failedSetPassword": "Failed Set Password", - "audio": "Audio", - "restore": "Restore", - "disableWarning": "Disable Warning", - "moderationsDesc": "Moderations Desc", - "providerHealthStatusAria": "Provider Health Status Aria", - "modelNamePlaceholder": "Model Name Placeholder", - "mcpQuickStartStep2": "Mcp Quick Start Step2", - "quickStart": "Quick Start", - "fullExportFailedWithError": "Full Export Failed With Error", - "loadingBackups": "Loading Backups", - "anthropicBaseUrlPlaceholder": "Anthropic Base Url Placeholder", - "description": "Description", - "noProviderFound": "No Provider Found", - "auto": "Auto", - "protocolsDescription": "Protocols Description", - "cloudSessionNote": "Cloud Session Note", - "advancedSettings": "Advanced Settings", - "defaultStrategy": "Default Strategy", - "purgeExpiredLogs": "Purge Expired Logs", - "justNow": "Just Now", - "providerTestFailed": "Provider Test Failed", - "openaiBaseUrlPlaceholder": "Openai Base Url Placeholder", - "image": "Image", - "failedCreateChain": "Failed Create Chain", - "importDatabase": "Import Database", - "allDataLocal": "All Data Local", - "sectionTitle": "Section Title", - "failedToggle": "Failed Toggle", - "editCombo": "Edit Combo", - "testResults": "Test Results", - "searchQuery": "Search Query", - "addCcCompatible": "Add Cc Compatible", - "duplicate": "Duplicate", - "createCombo": "Create Combo", - "searchTypeWeb": "Search Type Web", - "addChain": "Add Chain", - "prefixLabel": "Prefix Label", - "listModelsDesc": "List Models Desc", - "databaseSize": "Database Size", - "chainCreated": "Chain Created", - "providerTestTimeout": "Provider Test Timeout", - "routingStrategy": "Routing Strategy", - "translateAction": "Translate Action", - "exportFailed": "Export Failed", - "connectedVerificationPending": "Connected Verification Pending", - "a2aQuickStartTitle": "A2A Quick Start Title", - "couldNotTest": "Could Not Test", - "testAllCompatible": "Test All Compatible", - "anthropicCompatibleName": "Anthropic Compatible Name", - "disabling": "Disabling", - "failedEnable": "Failed Enable", - "categoryUtility": "Category Utility", - "customUrlOptional": "Custom Url Optional", - "localProviders": "Local Providers", - "comboNamePlaceholder": "Combo Name Placeholder", - "memoryRss": "Memory Rss", - "disableProvider": "Disable Provider", - "welcomeDesc": "Welcome Desc", - "nameLabel": "Name Label", - "allOperational": "All Operational", - "backupNow": "Backup Now", - "providerMaxRetriesAria": "Provider Max Retries Aria", - "textToSpeechDesc": "Text To Speech Desc", - "machineId": "Machine Id", - "globalProxy": "Global Proxy", - "hitsMisses": "Hits Misses", - "testDesc": "Test Desc", - "chatDesc": "Chat Desc", - "importSuccess": "Import Success", - "chat": "Chat", - "a2aQuickStartStep1": "A2A Quick Start Step1", - "importFailed": "Import Failed", - "inputPlaceholder": "Input Placeholder", - "providerModelsTitle": "Provider Models Title", - "lastBackup": "Last Backup", - "yourEndpoint": "Your Endpoint", - "autoDisableThresholdDesc": "Auto Disable Threshold Desc", - "rerankDesc": "Rerank Desc", - "modelsPathPlaceholder": "Models Path Placeholder", - "noCombosYet": "No Combos Yet", - "connectedVerificationPendingWithError": "Connected Verification Pending With Error", - "comboDefaultsGuideHint1": "Combo Defaults Guide Hint1", - "enableCloudTitle": "Enable Cloud Title", - "configuredProvidersHint": "Configured Providers Hint", - "paused": "Paused", - "llmProviders": "Llm Providers", - "enableCombo": "Enable Combo", - "removeProviderOverrideAria": "Remove Provider Override Aria", - "nodeVersion": "Node Version", - "openai": "Openai", - "exportFailedWithError": "Export Failed With Error", - "proxyConfigured": "Proxy Configured", - "concurrencyPerModel": "Concurrency Per Model", - "protocolTasksLabel": "Protocol Tasks Label", - "oauthProviders": "Oauth Providers", - "lockedCount": "Locked Count", - "deleteChainConfirm": "Delete Chain Confirm", - "recentTranslations": "Recent Translations", - "zedImportButton": "Zed Import Button", - "responsesDesc": "Responses Desc", - "testedCount": "Tested Count", - "providersCommaSeparatedPlaceholder": "Providers Comma Separated Placeholder", - "signatureDefaults": "Signature Defaults", - "errorCreating": "Error Creating", - "timeRangeYear": "Time Range Year", - "compatibleLabel": "Compatible Label", - "cloudDisabledSuccess": "Cloud Disabled Success", - "deleteConfirm": "Delete Confirm", - "check": "Check", - "safeSearch": "Safe Search", - "protocolLastActivity": "Protocol Last Activity", - "openMcpDashboard": "Open Mcp Dashboard", - "testBenchTab": "Test Bench Tab", - "chatPathLabel": "Chat Path Label", - "retryDelay": "Retry Delay", - "errorUpdating": "Error Updating", - "ideCliIntegrations": "Ide Cli Integrations", - "imageGeneration": "Image Generation", - "apiKeyRequired": "Api Key Required", - "resetAllTitle": "Reset All Title", - "connectionError": "Connection Error", - "modelName": "Model Name", - "apiKeyForCheck": "Api Key For Check", - "cloudRequestTimeout": "Cloud Request Timeout", - "showConfiguredOnly": "Show Configured Only", - "showFreeOnly": "Chỉ miễn phí", + "errorCount": "Số lượng lỗi", + "backupReasonManual": "Lý do sao lưu: Thủ công", + "safeSearchModerate": "Tìm kiếm an toàn: Trung bình", + "activeLimiters": "Các bộ giới hạn đang hoạt động", + "a2aCardTitle": "Tiêu đề thẻ A2A", + "cloudWorkerUnreachable": "Không thể kết nối tới trình xử lý đám mây", + "testFailed": "Kiểm tra thất bại", + "compatibleBaseUrlHint": "Gợi ý URL cơ sở tương thích", + "usageTracking": "Theo dõi mức sử dụng", + "disableCloudTitle": "Tiêu đề tắt đám mây", + "noConnections": "Không có kết nối", + "providerHealth": "Tình trạng nhà cung cấp", + "confirmDbImport": "Xác nhận nhập cơ sở dữ liệu", + "notAvailableSymbol": "Ký hiệu không khả dụng", + "backupsAvailable": "Bản sao lưu khả dụng", + "providerAuto": "Tự động chọn nhà cung cấp", + "newProviderNamePlaceholder": "Văn bản gợi ý cho tên nhà cung cấp mới", + "a2aQuickStartStep2": "Bắt đầu nhanh A2A - Bước 2", + "ok": "OK", + "available": "Khả dụng", + "noBackupYet": "Chưa có bản sao lưu", + "more": "Xem thêm", + "noCompatibleYet": "Chưa có mục tương thích", + "multiProvider": "Nhiều nhà cung cấp", + "repairEnvHint": "Gợi ý sửa lỗi biến môi trường", + "disablingCloud": "Đang tắt đám mây", + "testBench": "Bảng kiểm thử", + "valid": "Hợp lệ", + "cloudBenefitShare": "Chia sẻ lợi ích đám mây", + "mcpCardTitle": "Tiêu đề thẻ MCP", + "disableConfirm": "Xác nhận tắt", + "filters": "Bộ lọc", + "expirationBannerExpiredDesc": "Mô tả biểu ngữ hết hạn", + "saveComboDefaults": "Lưu combo làm mặc định", + "cloudConnectedVerified": "Đã kết nối đám mây và đã xác minh", + "uptime": "Thời gian hoạt động", + "compatibleProdPlaceholder": "Văn bản gợi ý cho URL production tương thích", + "fallbackChainsTitle": "Tiêu đề các chuỗi dự phòng", + "oauthLabel": "Nhãn OAuth", + "a2aCardDescription": "Mô tả thẻ A2A", + "okShort": "OK", + "maintenance": "Bảo trì", + "formatConverter": "Bộ chuyển đổi định dạng", + "zedImportNetworkError": "Lỗi mạng khi nhập Zed", + "apiKeyLabel": "Nhãn khóa API", + "noModelsForProvider": "Không có mô hình cho nhà cung cấp này", + "mcpCardDescription": "Mô tả thẻ MCP", + "apiTypeLabel": "Nhãn loại API", + "configuredProvidersLabel": "Nhãn nhà cung cấp đã cấu hình", + "maxRetriesLabel": "Nhãn số lần thử lại tối đa", + "title": "Tiêu đề", + "output": "Đầu ra", + "prefixHint": "Gợi ý tiền tố", + "skipWizard": "Bỏ qua trình hướng dẫn", + "failedCount": "Số lần thất bại", + "confirmDbImportDesc": "Mô tả xác nhận nhập cơ sở dữ liệu", + "entries": "Mục", + "until": "Đến", + "disableCombo": "Tắt combo", + "liveMonitorDescriptionPrefix": "Tiền tố mô tả giám sát trực tiếp", + "runningCount": "Số lượng đang chạy", + "noActiveConnectionsInGroup": "Không có kết nối đang hoạt động trong nhóm", + "savedSuccessfully": "Đã lưu thành công", + "systemStorage": "Dung lượng lưu trữ hệ thống", + "videoDesc": "Mô tả video", + "maxResults": "Số kết quả tối đa", + "timeRangeMonth": "Khoảng thời gian: Tháng", + "testSummary": "Tóm tắt kiểm tra", + "failedSetPassword": "Đặt mật khẩu không thành công", + "audio": "Âm thanh", + "restore": "Khôi phục", + "disableWarning": "Cảnh báo khi tắt", + "moderationsDesc": "Mô tả kiểm duyệt", + "providerHealthStatusAria": "Nhãn ARIA cho trạng thái sức khỏe của nhà cung cấp", + "modelNamePlaceholder": "Văn bản gợi ý cho tên mô hình", + "mcpQuickStartStep2": "Bắt đầu nhanh MCP - Bước 2", + "quickStart": "Bắt đầu nhanh", + "fullExportFailedWithError": "Xuất toàn bộ thất bại kèm lỗi", + "loadingBackups": "Đang tải các bản sao lưu", + "anthropicBaseUrlPlaceholder": "Văn bản gợi ý cho URL cơ sở của Anthropic", + "description": "Mô tả", + "noProviderFound": "Không tìm thấy nhà cung cấp", + "auto": "Tự động", + "protocolsDescription": "Mô tả các giao thức", + "cloudSessionNote": "Ghi chú phiên đám mây", + "advancedSettings": "Cài đặt nâng cao", + "defaultStrategy": "Chiến lược mặc định", + "purgeExpiredLogs": "Xóa nhật ký đã hết hạn", + "justNow": "Vừa xong", + "providerTestFailed": "Kiểm tra nhà cung cấp thất bại", + "openaiBaseUrlPlaceholder": "Văn bản gợi ý cho URL cơ sở của OpenAI", + "image": "Hình ảnh", + "failedCreateChain": "Tạo chuỗi không thành công", + "importDatabase": "Nhập cơ sở dữ liệu", + "allDataLocal": "Toàn bộ dữ liệu được lưu cục bộ", + "sectionTitle": "Tiêu đề mục", + "failedToggle": "Chuyển đổi không thành công", + "editCombo": "Sửa combo", + "testResults": "Kết quả kiểm tra", + "searchQuery": "Truy vấn tìm kiếm", + "addCcCompatible": "Thêm CC tương thích", + "duplicate": "Nhân bản", + "createCombo": "Tạo combo", + "searchTypeWeb": "Loại tìm kiếm: Web", + "addChain": "Thêm chuỗi", + "prefixLabel": "Nhãn tiền tố", + "listModelsDesc": "Mô tả danh sách mô hình", + "databaseSize": "Kích thước cơ sở dữ liệu", + "chainCreated": "Đã tạo chuỗi", + "providerTestTimeout": "Hết thời gian kiểm tra nhà cung cấp", + "routingStrategy": "Chiến lược định tuyến", + "translateAction": "Hành động dịch", + "exportFailed": "Xuất thất bại", + "connectedVerificationPending": "Đã kết nối, đang chờ xác minh", + "a2aQuickStartTitle": "Tiêu đề bắt đầu nhanh A2A", + "couldNotTest": "Không thể kiểm tra", + "testAllCompatible": "Kiểm tra tất cả mục tương thích", + "anthropicCompatibleName": "Tên tương thích Anthropic", + "disabling": "Đang tắt", + "failedEnable": "Không thể bật", + "categoryUtility": "Danh mục: Tiện ích", + "customUrlOptional": "URL tùy chỉnh (không bắt buộc)", + "localProviders": "Nhà cung cấp cục bộ", + "comboNamePlaceholder": "Văn bản gợi ý cho tên combo", + "memoryRss": "Bộ nhớ RSS", + "disableProvider": "Tắt nhà cung cấp", + "welcomeDesc": "Mô tả chào mừng", + "nameLabel": "Nhãn tên", + "allOperational": "Tất cả đang hoạt động", + "backupNow": "Sao lưu ngay", + "providerMaxRetriesAria": "Nhãn ARIA cho số lần thử lại tối đa của nhà cung cấp", + "textToSpeechDesc": "Mô tả chuyển văn bản thành giọng nói", + "machineId": "ID máy", + "globalProxy": "Proxy toàn cục", + "hitsMisses": "Số lần trúng và trượt", + "testDesc": "Mô tả kiểm tra", + "chatDesc": "Mô tả trò chuyện", + "importSuccess": "Nhập thành công", + "chat": "Trò chuyện", + "a2aQuickStartStep1": "Bắt đầu nhanh A2A - Bước 1", + "importFailed": "Nhập thất bại", + "inputPlaceholder": "Văn bản gợi ý cho dữ liệu đầu vào", + "providerModelsTitle": "Tiêu đề mô hình nhà cung cấp", + "lastBackup": "Sao lưu gần nhất", + "yourEndpoint": "Endpoint của bạn", + "autoDisableThresholdDesc": "Mô tả ngưỡng tự động tắt", + "rerankDesc": "Mô tả rerank", + "modelsPathPlaceholder": "Văn bản gợi ý cho đường dẫn mô hình", + "noCombosYet": "Chưa có combo nào", + "connectedVerificationPendingWithError": "Đã kết nối - đang chờ xác minh (có lỗi)", + "comboDefaultsGuideHint1": "Gợi ý 1 - Hướng dẫn giá trị mặc định combo", + "enableCloudTitle": "Tiêu đề bật đám mây", + "configuredProvidersHint": "Gợi ý nhà cung cấp đã cấu hình", + "paused": "Đã tạm dừng", + "llmProviders": "Nhà cung cấp LLM", + "enableCombo": "Bật combo", + "removeProviderOverrideAria": "Nhãn ARIA để xóa ghi đè nhà cung cấp", + "nodeVersion": "Phiên bản Node", + "openai": "OpenAI", + "exportFailedWithError": "Xuất thất bại do lỗi", + "proxyConfigured": "Đã cấu hình proxy", + "concurrencyPerModel": "Số tác vụ đồng thời cho mỗi mô hình", + "protocolTasksLabel": "Nhãn tác vụ giao thức", + "oauthProviders": "Nhà cung cấp OAuth", + "lockedCount": "Số lượng đã khóa", + "deleteChainConfirm": "Xác nhận xóa chuỗi", + "recentTranslations": "Bản dịch gần đây", + "zedImportButton": "Nút nhập từ Zed", + "responsesDesc": "Mô tả Responses", + "testedCount": "Số lượng đã kiểm tra", + "providersCommaSeparatedPlaceholder": "Văn bản gợi ý: các nhà cung cấp, phân tách bằng dấu phẩy", + "signatureDefaults": "Giá trị mặc định cho chữ ký", + "errorCreating": "Lỗi khi tạo", + "timeRangeYear": "Khoảng thời gian: năm", + "compatibleLabel": "Tương thích", + "cloudDisabledSuccess": "Đã tắt đám mây thành công", + "deleteConfirm": "Xác nhận xóa", + "check": "Kiểm tra", + "safeSearch": "Tìm kiếm an toàn", + "protocolLastActivity": "Hoạt động gần nhất của giao thức", + "openMcpDashboard": "Mở bảng điều khiển MCP", + "testBenchTab": "Khu vực kiểm thử", + "chatPathLabel": "Nhãn đường dẫn trò chuyện", + "retryDelay": "Độ trễ thử lại", + "errorUpdating": "Lỗi khi cập nhật", + "ideCliIntegrations": "Tích hợp IDE/CLI", + "imageGeneration": "Tạo ảnh", + "apiKeyRequired": "Cần có khóa API", + "resetAllTitle": "Tiêu đề đặt lại tất cả", + "connectionError": "Lỗi kết nối", + "modelName": "Tên mô hình", + "apiKeyForCheck": "Khóa API để kiểm tra", + "cloudRequestTimeout": "Thời gian chờ của yêu cầu đám mây", + "showConfiguredOnly": "Chỉ hiển thị mục đã cấu hình", + "showFreeOnly": "Chỉ hiển thị mục miễn phí", "addFirstProvider": "Thêm nhà cung cấp đầu tiên của bạn", "addFirstProviderDesc": "Kết nối nhà cung cấp AI để bắt đầu định tuyến các yêu cầu thông qua OmniRoute. Bạn có thể sử dụng nhà cung cấp miễn phí, khóa API hoặc tài khoản OAuth.", "learnMore": "Tìm hiểu thêm", - "includeDomains": "Include Domains", - "promptCache": "Prompt Cache", - "cloudConnected": "Cloud Connected", - "deleteChain": "Delete Chain", - "chatPathPlaceholder": "Chat Path Placeholder", - "databasePath": "Database Path", - "usingLocalServer": "Using Local Server", - "globalComboConfig": "Global Combo Config", - "backupFailed": "Backup Failed", - "tabProtocols": "Tab Protocols", - "continue": "Continue", - "categorySearch": "Category Search", - "rateLimitStatus": "Rate Limit Status", - "repairEnvSuccess": "Repair Env Success", - "nameRequired": "Name Required", - "country": "Country", - "trackMetricsDesc": "Track Metrics Desc", - "durationSecondsShort": "Duration Seconds Short", - "formatConverterDescription": "Format Converter Description", - "cloudBenefitAccess": "Cloud Benefit Access", - "maxRetries": "Max Retries", - "queueTimeout": "Queue Timeout", - "addProvider": "Add Provider", - "realtime": "Realtime", - "totalTranslations": "Total Translations", - "protocolActiveStreamsLabel": "Protocol Active Streams Label", - "repairEnv": "Repair Env", - "modelsCount": "Models Count", - "viewBackups": "View Backups", - "responsesApi": "Responses Api", - "copyComboName": "Copy Combo Name", - "failures": "Failures", - "failedUpdate": "Failed Update", - "imageDesc": "Image Desc", - "failedCreate": "Failed Create", - "remainingOfLimit": "Remaining Of Limit", - "protocolsTitle": "Protocols Title", - "expirationBannerExpiringSoonDesc": "Expiration Banner Expiring Soon Desc", - "source": "Source", - "failed": "Failed", - "apiKeyMgmt": "Api Key Mgmt", - "mcpQuickStartStep1": "Mcp Quick Start Step1", - "runTest": "Run Test", - "loadingFallbackChains": "Loading Fallback Chains", - "healthy": "Healthy", - "version": "Version", - "saveBlockWeighted": "Save Block Weighted", - "zedImportNone": "Zed Import None", - "noBackupsYet": "No Backups Yet", - "noGlobalProxy": "No Global Proxy", - "noModels": "No Models", - "stickyLimit": "Sticky Limit", - "passedCount": "Passed Count", - "zedImportFailed": "Zed Import Failed", - "saving": "Saving", - "testAll": "Test All", - "globalProxyDesc": "Global Proxy Desc", - "latencyP99": "Latency P99", - "connectingToCloud": "Connecting To Cloud", - "responses": "Responses", - "errorDeleting": "Error Deleting", - "openaiPrefixPlaceholder": "Openai Prefix Placeholder", - "enterPassword": "Enter Password", - "openA2aDashboard": "Open A2A Dashboard", - "enableProvider": "Enable Provider", - "modeTest": "Mode Test", - "failedDeleteChain": "Failed Delete Chain", - "providerDesc": "Provider Desc", - "templateLoadHint": "Template Load Hint", - "lastFailure": "Last Failure", - "moveDown": "Move Down", - "providerLabel": "Provider Label", - "clearCacheFailed": "Clear Cache Failed", - "imagesGenerations": "Images Generations", - "repairEnvWorking": "Repair Env Working", - "millisecondsShort": "Milliseconds Short", - "globalLabel": "Global Label", - "failuresPlural": "Failures Plural", - "completionsLegacyDesc": "Completions Legacy Desc", - "searchProviders": "Search Providers", - "chatPathHint": "Chat Path Hint", - "defaultStrategyDesc": "Default Strategy Desc", - "latencyP95": "Latency P95", - "textToSpeech": "Text To Speech", - "searchType": "Search Type", - "messages": "Messages", - "aggregatorsGateways": "Aggregators Gateways", - "comboStrategyAria": "Combo Strategy Aria", - "input": "Input", - "testingConnection": "Testing Connection", - "excludeDomains": "Exclude Domains", - "webCookieProviders": "Web Cookie Providers", - "allTestsPassed": "All Tests Passed", - "openaiCompatibleName": "Openai Compatible Name", - "warningCostOptimizedPartialPricing": "Warning Cost Optimized Partial Pricing", - "comboDefaultsGuideTitle": "Combo Defaults Guide Title", - "hoursAgo": "Hours Ago", - "notAvailable": "Not Available", - "skipAndContinue": "Skip And Continue", - "moderations": "Moderations", - "proxyConfig": "Proxy Config", - "upstreamProxyProviders": "Upstream Proxy Providers", - "exportAll": "Export All", - "queuedCount": "Queued Count", - "resetAll": "Reset All", - "noTranslations": "No Translations", - "avgLatency": "Avg Latency", - "throttleStatus": "Throttle Status", - "backupRetentionDesc": "Backup Retention Desc", - "noCBData": "No Cb Data", - "chainDeleted": "Chain Deleted", - "timeLeft": "Time Left", - "expirationBannerExpired": "Expiration Banner Expired", - "language": "Language", - "invalidFileType": "Invalid File Type", - "monitoredProviders": "Monitored Providers", - "errors": "Errors", + "includeDomains": "Bao gồm miền", + "promptCache": "Bộ nhớ đệm prompt", + "cloudConnected": "Đã kết nối với đám mây", + "deleteChain": "Xóa chuỗi", + "chatPathPlaceholder": "Văn bản gợi ý đường dẫn trò chuyện", + "databasePath": "Đường dẫn cơ sở dữ liệu", + "usingLocalServer": "Đang sử dụng máy chủ cục bộ", + "globalComboConfig": "Cấu hình tổ hợp toàn cục", + "backupFailed": "Sao lưu thất bại", + "tabProtocols": "Thẻ giao thức", + "continue": "Tiếp tục", + "categorySearch": "Tìm kiếm danh mục", + "rateLimitStatus": "Trạng thái giới hạn tần suất", + "repairEnvSuccess": "Sửa môi trường thành công", + "nameRequired": "Cần có tên", + "country": "Quốc gia", + "trackMetricsDesc": "Mô tả theo dõi số liệu", + "durationSecondsShort": "Thời lượng (giây)", + "formatConverterDescription": "Mô tả bộ chuyển đổi định dạng", + "cloudBenefitAccess": "Quyền truy cập các lợi ích của đám mây", + "maxRetries": "Số lần thử lại tối đa", + "queueTimeout": "Thời gian chờ hàng đợi", + "addProvider": "Thêm nhà cung cấp", + "realtime": "Theo thời gian thực", + "totalTranslations": "Tổng số bản dịch", + "protocolActiveStreamsLabel": "Nhãn luồng hoạt động của giao thức", + "repairEnv": "Sửa môi trường", + "modelsCount": "Số lượng mô hình", + "viewBackups": "Xem bản sao lưu", + "responsesApi": "API Responses", + "copyComboName": "Sao chép tên tổ hợp", + "failures": "Số lần thất bại", + "failedUpdate": "Cập nhật thất bại", + "imageDesc": "Mô tả hình ảnh", + "failedCreate": "Tạo thất bại", + "remainingOfLimit": "Số lượng giới hạn còn lại", + "protocolsTitle": "Tiêu đề giao thức", + "expirationBannerExpiringSoonDesc": "Mô tả biểu ngữ sắp hết hạn", + "source": "Nguồn", + "failed": "Thất bại", + "apiKeyMgmt": "Quản lý khóa API", + "mcpQuickStartStep1": "Bước 1 - Khởi động nhanh MCP", + "runTest": "Chạy kiểm tra", + "loadingFallbackChains": "Đang tải chuỗi dự phòng", + "healthy": "Bình thường", + "version": "Phiên bản", + "saveBlockWeighted": "Lưu khối có trọng số", + "zedImportNone": "Không có gì để nhập từ Zed", + "noBackupsYet": "Chưa có bản sao lưu nào", + "noGlobalProxy": "Không có proxy toàn cục", + "noModels": "Không có mô hình", + "stickyLimit": "Giới hạn Sticky", + "passedCount": "Số lượng đạt", + "zedImportFailed": "Nhập từ Zed thất bại", + "saving": "Đang lưu", + "testAll": "Kiểm tra tất cả", + "globalProxyDesc": "Mô tả proxy toàn cục", + "latencyP99": "Độ trễ P99", + "connectingToCloud": "Đang kết nối với đám mây", + "responses": "Phản hồi", + "errorDeleting": "Lỗi khi xóa", + "openaiPrefixPlaceholder": "Văn bản gợi ý tiền tố OpenAI", + "enterPassword": "Nhập mật khẩu", + "openA2aDashboard": "Mở bảng điều khiển A2A", + "enableProvider": "Bật nhà cung cấp", + "modeTest": "Chế độ kiểm tra", + "failedDeleteChain": "Xóa chuỗi thất bại", + "providerDesc": "Mô tả nhà cung cấp", + "templateLoadHint": "Gợi ý tải mẫu", + "lastFailure": "Lỗi gần nhất", + "moveDown": "Di chuyển xuống", + "providerLabel": "Nhãn nhà cung cấp", + "clearCacheFailed": "Xóa cache thất bại", + "imagesGenerations": "Tạo hình ảnh", + "repairEnvWorking": "Đang sửa môi trường", + "millisecondsShort": "Mili giây (viết tắt)", + "globalLabel": "Nhãn toàn cục", + "failuresPlural": "Số lần thất bại (số nhiều)", + "completionsLegacyDesc": "Mô tả tính năng hoàn tất (cũ)", + "searchProviders": "Tìm kiếm nhà cung cấp", + "chatPathHint": "Gợi ý đường dẫn chat", + "defaultStrategyDesc": "Mô tả chiến lược mặc định", + "latencyP95": "Độ trễ P95", + "textToSpeech": "Chuyển văn bản thành giọng nói", + "searchType": "Loại tìm kiếm", + "messages": "Tin nhắn", + "aggregatorsGateways": "Bộ tổng hợp / cổng kết nối", + "comboStrategyAria": "Nhãn ARIA cho chiến lược kết hợp", + "input": "Đầu vào", + "testingConnection": "Đang kiểm tra kết nối", + "excludeDomains": "Loại trừ miền", + "webCookieProviders": "Nhà cung cấp cookie web", + "allTestsPassed": "Tất cả kiểm tra đều đạt", + "openaiCompatibleName": "Tên tương thích OpenAI", + "warningCostOptimizedPartialPricing": "Cảnh báo: tính năng tối ưu chi phí chỉ có thông tin định giá một phần", + "comboDefaultsGuideTitle": "Tiêu đề hướng dẫn về giá trị mặc định của combo", + "hoursAgo": "Số giờ trước", + "notAvailable": "Không khả dụng", + "skipAndContinue": "Bỏ qua và tiếp tục", + "moderations": "Kiểm duyệt", + "proxyConfig": "Cấu hình proxy", + "upstreamProxyProviders": "Nhà cung cấp proxy thượng nguồn", + "exportAll": "Xuất tất cả", + "queuedCount": "Số lượng đang chờ", + "resetAll": "Đặt lại tất cả", + "noTranslations": "Không có bản dịch", + "avgLatency": "Độ trễ trung bình", + "throttleStatus": "Trạng thái giới hạn tốc độ", + "backupRetentionDesc": "Mô tả thời gian lưu giữ bản sao lưu", + "noCBData": "Không có dữ liệu CB", + "chainDeleted": "Đã xóa chuỗi", + "timeLeft": "Thời gian còn lại", + "expirationBannerExpired": "Biểu ngữ đã hết hạn", + "language": "Ngôn ngữ", + "invalidFileType": "Loại tệp không hợp lệ", + "monitoredProviders": "Nhà cung cấp được giám sát", + "errors": "Lỗi", "heap": "Heap", "chatCompletions": "Chat Completions", - "exampleTemplatesHint": "Example Templates Hint", - "retryDelayLabel": "Retry Delay Label", - "audioTranscription": "Audio Transcription", - "fallbackChainsDesc": "Fallback Chains Desc", - "exampleTemplates": "Example Templates", - "connectionsCount": "Connections Count", - "modelsPathLabel": "Models Path Label", - "activeProvidersHint": "Active Providers Hint", - "activeLockouts": "Active Lockouts", - "invalid": "Invalid", - "skipPassword": "Skip Password", - "moveUp": "Move Up", - "timeRange": "Time Range", - "stickyLimitDesc": "Sticky Limit Desc", - "cloudBenefitEdge": "Cloud Benefit Edge", - "custom": "Custom", - "verifying": "Verifying", - "baseUrlLabel": "Base Url Label", - "setPassword": "Set Password", - "safeSearchStrict": "Safe Search Strict", - "noChangesSinceBackup": "No Changes Since Backup", - "modelsPathHint": "Models Path Hint", - "audioTranscriptions": "Audio Transcriptions", - "testCombo": "Test Combo", - "mcpQuickStartTitle": "Mcp Quick Start Title", - "comboUpdated": "Combo Updated", - "weighted": "Weighted", - "providers": "Providers", - "ccCompatibleLabel": "Cc Compatible Label", - "noFallbackChainsDesc": "No Fallback Chains Desc", - "yesImport": "Yes Import", - "lockoutsAutoRefreshHint": "Lockouts Auto Refresh Hint", - "tabApis": "Tab Apis", - "sectionDescription": "Section Description", - "filter": "Filter", - "purgeLogsFailed": "Purge Logs Failed", - "latency": "Latency", - "testAllOAuth": "Test All O Auth", - "mcpQuickStartStep3": "Mcp Quick Start Step3", - "repairEnvFailed": "Repair Env Failed", - "zedImportHint": "Zed Import Hint", - "modelsAcrossEndpoints": "Models Across Endpoints", - "autoDisableBannedAccounts": "Auto Disable Banned Accounts", - "securityDesc": "Security Desc", - "listModels": "List Models", - "backupRestore": "Backup Restore", - "target": "Target", - "zedImportSuccess": "Zed Import Success", - "lastHeaderUpdate": "Last Header Update", - "categoryCore": "Category Core", - "noFallbackChains": "No Fallback Chains", - "noSearchProviders": "No Search Providers", - "autoBalance": "Auto Balance", - "noModelsYet": "No Models Yet", - "signatureFamily": "Signature Family", - "externalApiCalls": "External Api Calls", - "providerOverridesDesc": "Provider Overrides Desc", - "signatureTool": "Signature Tool", - "connectionFailed": "Connection Failed", - "activeLimitersPlural": "Active Limiters Plural", - "doneDesc": "Done Desc", - "down": "Down", - "noDataYet": "No Data Yet", - "activeProviders": "Active Providers", - "nameInvalid": "Name Invalid", - "skip": "Skip", - "createChain": "Create Chain", - "audioSpeech": "Audio Speech", - "cacheCleared": "Cache Cleared", - "searchTypeNews": "Search Type News", - "durationMillisecondsShort": "Duration Milliseconds Short", - "addOpenAICompatible": "Add Open Ai Compatible", - "chatTesterTab": "Chat Tester Tab", - "queued": "Queued", - "domainPlaceholder": "Domain Placeholder", - "durationMinutesShort": "Duration Minutes Short", - "verifyingConnection": "Verifying Connection", - "imageProviders": "Image Providers", - "protocolToolsLabel": "Protocol Tools Label", - "queryPlaceholder": "Query Placeholder", - "videoGeneration": "Video Generation", - "timeRangeWeek": "Time Range Week", - "limitExhausted": "Limit Exhausted", - "failedDisable": "Failed Disable", - "inMemoryNote": "In Memory Note", - "compatibleHint": "Compatible Hint", - "errorShort": "Error Short", - "advancedHint": "Advanced Hint", - "restoreFailed": "Restore Failed", - "searchProvidersHeading": "Search Providers Heading", - "comboName": "Combo Name", - "autoDisableDescription": "Auto Disable Description", - "embeddingsDesc": "Embeddings Desc", - "operational": "Operational", - "testAllApiKey": "Test All Api Key", - "backupCreated": "Backup Created", - "errorDuringImport": "Error During Import", - "comboDefaultsGuideHint2": "Combo Defaults Guide Hint2", - "connecting": "Connecting", - "fillModelAndProviders": "Fill Model And Providers", - "syncing": "Syncing", - "resetConfirm": "Reset Confirm", - "trackMetrics": "Track Metrics", - "successful": "Successful", - "recovering": "Recovering", - "autoDisableThreshold": "Auto Disable Threshold", + "exampleTemplatesHint": "Gợi ý mẫu ví dụ", + "retryDelayLabel": "Nhãn độ trễ thử lại", + "audioTranscription": "Chuyển âm thanh thành văn bản", + "fallbackChainsDesc": "Mô tả chuỗi dự phòng", + "exampleTemplates": "Mẫu ví dụ", + "connectionsCount": "Số lượng kết nối", + "modelsPathLabel": "Nhãn đường dẫn mô hình", + "activeProvidersHint": "Gợi ý nhà cung cấp đang hoạt động", + "activeLockouts": "Các lệnh khóa đang hoạt động", + "invalid": "Không hợp lệ", + "skipPassword": "Bỏ qua mật khẩu", + "moveUp": "Di chuyển lên", + "timeRange": "Khoảng thời gian", + "stickyLimitDesc": "Mô tả giới hạn cố định", + "cloudBenefitEdge": "Lợi ích của điện toán đám mây tại biên", + "custom": "Tùy chỉnh", + "verifying": "Đang xác minh", + "baseUrlLabel": "Nhãn URL cơ sở", + "setPassword": "Đặt mật khẩu", + "safeSearchStrict": "Tìm kiếm an toàn nghiêm ngặt", + "noChangesSinceBackup": "Không có thay đổi kể từ lần sao lưu", + "modelsPathHint": "Gợi ý đường dẫn mô hình", + "audioTranscriptions": "Chuyển âm thanh thành văn bản", + "testCombo": "Kiểm tra combo", + "mcpQuickStartTitle": "Tiêu đề bắt đầu nhanh MCP", + "comboUpdated": "Đã cập nhật combo", + "weighted": "Có trọng số", + "providers": "Nhà cung cấp", + "ccCompatibleLabel": "Tương thích với CC", + "noFallbackChainsDesc": "Mô tả khi không có chuỗi dự phòng", + "yesImport": "Có, nhập", + "lockoutsAutoRefreshHint": "Gợi ý tự động làm mới trạng thái khóa", + "tabApis": "Tab API", + "sectionDescription": "Mô tả phần", + "filter": "Bộ lọc", + "purgeLogsFailed": "Không thể xóa nhật ký", + "latency": "Độ trễ", + "testAllOAuth": "Kiểm tra tất cả OAuth", + "mcpQuickStartStep3": "Bước 3 của hướng dẫn bắt đầu nhanh MCP", + "repairEnvFailed": "Sửa biến môi trường thất bại", + "zedImportHint": "Gợi ý nhập Zed", + "modelsAcrossEndpoints": "Mô hình trên các endpoint", + "autoDisableBannedAccounts": "Tự động tắt tài khoản bị cấm", + "securityDesc": "Mô tả bảo mật", + "listModels": "Danh sách mô hình", + "backupRestore": "Sao lưu và khôi phục", + "target": "Mục tiêu", + "zedImportSuccess": "Đã nhập Zed thành công", + "lastHeaderUpdate": "Lần cập nhật header gần nhất", + "categoryCore": "Danh mục cốt lõi", + "noFallbackChains": "Không có chuỗi dự phòng", + "noSearchProviders": "Không có nhà cung cấp tìm kiếm", + "autoBalance": "Tự động cân bằng", + "noModelsYet": "Chưa có mô hình nào", + "signatureFamily": "Họ chữ ký", + "externalApiCalls": "Các lệnh gọi API bên ngoài", + "providerOverridesDesc": "Mô tả ghi đè của nhà cung cấp", + "signatureTool": "Công cụ chữ ký", + "connectionFailed": "Kết nối thất bại", + "activeLimitersPlural": "Các bộ giới hạn đang hoạt động (số nhiều)", + "doneDesc": "Mô tả hoàn tất", + "down": "Ngừng hoạt động", + "noDataYet": "Chưa có dữ liệu", + "activeProviders": "Nhà cung cấp đang hoạt động", + "nameInvalid": "Tên không hợp lệ", + "skip": "Bỏ qua", + "createChain": "Tạo chuỗi", + "audioSpeech": "Giọng Nói", + "cacheCleared": "Đã xóa bộ nhớ đệm", + "searchTypeNews": "Loại tìm kiếm: tin tức", + "durationMillisecondsShort": "Thời lượng (ms)", + "addOpenAICompatible": "Thêm nhà cung cấp tương thích OpenAI", + "chatTesterTab": "Trình kiểm tra chat", + "queued": "Đang chờ", + "domainPlaceholder": "Trình giữ chỗ tên miền", + "durationMinutesShort": "Thời lượng (phút)", + "verifyingConnection": "Đang xác minh kết nối", + "imageProviders": "Nhà cung cấp hình ảnh", + "protocolToolsLabel": "Nhãn công cụ giao thức", + "queryPlaceholder": "Trình giữ chỗ truy vấn", + "videoGeneration": "Tạo video", + "timeRangeWeek": "Khoảng thời gian: tuần", + "limitExhausted": "Đã hết giới hạn", + "failedDisable": "Tắt thất bại", + "inMemoryNote": "Ghi chú trong bộ nhớ", + "compatibleHint": "Gợi ý tương thích", + "errorShort": "Lỗi (ngắn)", + "advancedHint": "Gợi ý nâng cao", + "restoreFailed": "Khôi phục thất bại", + "searchProvidersHeading": "Tiêu đề nhà cung cấp tìm kiếm", + "comboName": "Tên tổ hợp", + "autoDisableDescription": "Mô tả tự động tắt", + "embeddingsDesc": "Mô tả phần nhúng", + "operational": "Đang hoạt động", + "testAllApiKey": "Kiểm tra tất cả khóa API", + "backupCreated": "Đã tạo bản sao lưu", + "errorDuringImport": "Lỗi khi nhập", + "comboDefaultsGuideHint2": "Gợi ý 2 trong hướng dẫn giá trị mặc định của tổ hợp", + "connecting": "Đang kết nối", + "fillModelAndProviders": "Điền mô hình và nhà cung cấp", + "syncing": "Đang đồng bộ", + "resetConfirm": "Xác nhận đặt lại", + "trackMetrics": "Theo dõi số liệu", + "successful": "Thành công", + "recovering": "Đang khôi phục", + "autoDisableThreshold": "Ngưỡng tự động tắt", "anthropic": "Anthropic", - "syncingData": "Syncing Data", - "cloudBenefitPorts": "Cloud Benefit Ports", - "compatibleProviders": "Compatible Providers", - "freeTierProviders": "Nhà cung cấp bậc miễn phí", - "freeTierLabel": "Cấp miễn phí có sẵn", - "freeTierProvidersDesc": "Các nhà cung cấp có cấp độ miễn phí — một số yêu cầu đăng ký khóa API, một số khác không cần thông tin xác thực nào cả.", - "clearCache": "Clear Cache", - "reqs": "Reqs", - "addAnthropicCompatible": "Add Anthropic Compatible", - "apiKeyProviders": "Api Key Providers", - "tabsAria": "Tabs Aria", - "resetting": "Resetting", - "millisecondsAbbr": "Milliseconds Abbr", - "backupReasonPreRestore": "Backup Reason Pre Restore", - "disableCloud": "Disable Cloud", - "newProviderNameAria": "New Provider Name Aria", - "passwordsMismatch": "Passwords Mismatch", - "a2aQuickStartStep3": "A2A Quick Start Step3", - "liveMonitorDescriptionSuffix": "Live Monitor Description Suffix", - "failedAddProvider": "Failed Add Provider", - "addAtLeastOneProvider": "Add At Least One Provider", - "reasonSeparator": "Reason Separator", - "zedImporting": "Zed Importing", - "confirmPasswordPlaceholder": "Confirm Password Placeholder", - "whatYouGet": "What You Get", - "signatureSession": "Signature Session", - "errorCountNoCode": "Error Count No Code", - "testing": "Testing", - "providersCommaSeparated": "Providers Comma Separated", - "exportDatabase": "Export Database", - "hitRate": "Hit Rate", - "completionsLegacy": "Completions Legacy", - "removeModel": "Remove Model", - "timeRangeDay": "Time Range Day", - "cloudRequestFailed": "Cloud Request Failed", - "updatedAt": "Updated At", - "monitoredProvidersHint": "Monitored Providers Hint", - "connectionSuccessful": "Connection Successful", - "latencyP50": "Latency P50", - "logsDeleted": "Logs Deleted", - "chatTester": "Chat Tester", - "safeSearchOff": "Safe Search Off", - "nameHint": "Name Hint", - "debugToggle": "Debug Toggle", + "syncingData": "Đang đồng bộ dữ liệu", + "cloudBenefitPorts": "Lợi ích của cổng kết nối đám mây", + "compatibleProviders": "Nhà cung cấp tương thích", + "freeTierProviders": "Nhà cung cấp gói miễn phí", + "freeTierLabel": "Có sẵn gói miễn phí", + "freeTierProvidersDesc": "Các nhà cung cấp có gói miễn phí — một số yêu cầu đăng ký để nhận khóa API, một số khác hoàn toàn không cần thông tin xác thực.", + "clearCache": "Xóa bộ nhớ đệm", + "reqs": "Yêu cầu", + "addAnthropicCompatible": "Thêm nhà cung cấp tương thích với Anthropic", + "apiKeyProviders": "Nhà cung cấp dùng khóa API", + "tabsAria": "ARIA cho các tab", + "resetting": "Đang đặt lại", + "millisecondsAbbr": "Viết tắt của mili giây (ms)", + "backupReasonPreRestore": "Lý do sao lưu trước khi khôi phục", + "disableCloud": "Tắt dịch vụ đám mây", + "newProviderNameAria": "ARIA cho tên nhà cung cấp mới", + "passwordsMismatch": "Mật khẩu không khớp", + "a2aQuickStartStep3": "Bước 3 của phần bắt đầu nhanh A2A", + "liveMonitorDescriptionSuffix": "Hậu tố mô tả giám sát trực tiếp", + "failedAddProvider": "Không thể thêm nhà cung cấp", + "addAtLeastOneProvider": "Thêm ít nhất một nhà cung cấp", + "reasonSeparator": "Dấu phân cách lý do", + "zedImporting": "Đang nhập Zed", + "confirmPasswordPlaceholder": "Văn bản gợi ý xác nhận mật khẩu", + "whatYouGet": "Bạn nhận được gì", + "signatureSession": "Phiên chữ ký", + "errorCountNoCode": "Số lỗi không có mã", + "testing": "Đang kiểm tra", + "providersCommaSeparated": "Các nhà cung cấp, phân tách bằng dấu phẩy", + "exportDatabase": "Xuất cơ sở dữ liệu", + "hitRate": "Tỷ lệ truy cập", + "completionsLegacy": "Completions (cũ)", + "removeModel": "Xóa Mô Hình", + "timeRangeDay": "Khoảng thời gian: ngày", + "cloudRequestFailed": "Yêu cầu lên đám mây không thành công", + "updatedAt": "Cập nhật lúc", + "monitoredProvidersHint": "Gợi ý về các nhà cung cấp được giám sát", + "connectionSuccessful": "Kết nối thành công", + "latencyP50": "Độ trễ P50", + "logsDeleted": "Nhật ký đã bị xóa", + "chatTester": "Công cụ kiểm tra trò chuyện", + "safeSearchOff": "Tắt tìm kiếm an toàn", + "nameHint": "Gợi ý tên", + "debugToggle": "Bật/tắt gỡ lỗi", "embedding": "Embedding", - "issuesLabel": "Issues Label", - "optionAny": "Option Any", - "maxNestingDepth": "Max Nesting Depth", - "rerank": "Rerank", - "checking": "Checking", - "getStarted": "Get Started", - "restoreSuccess": "Restore Success", - "issuesDetected": "Issues Detected", - "signatureCache": "Signature Cache", - "modelLockouts": "Model Lockouts", - "usingCloudProxy": "Using Cloud Proxy", - "loadingHealth": "Loading Health", - "providerOverrides": "Provider Overrides", - "audioTranscriptionDesc": "Audio Transcription Desc", - "learnedFromHeaders": "Learned From Headers", - "totalRequests": "Total Requests", - "cloudUnstableNote": "Cloud Unstable Note", - "gamificationAdmin": "Quản trị viên gamification", + "issuesLabel": "Nhãn vấn đề", + "optionAny": "Bất kỳ", + "maxNestingDepth": "Độ sâu lồng ghép tối đa", + "rerank": "Xếp hạng lại", + "checking": "Đang kiểm tra", + "getStarted": "Bắt đầu", + "restoreSuccess": "Khôi phục thành công", + "issuesDetected": "Đã phát hiện vấn đề", + "signatureCache": "Bộ nhớ đệm chữ ký", + "modelLockouts": "Mô hình bị khóa", + "usingCloudProxy": "Đang sử dụng proxy trên đám mây", + "loadingHealth": "Đang tải trạng thái hệ thống", + "providerOverrides": "Ghi đè nhà cung cấp", + "audioTranscriptionDesc": "Mô tả chuyển giọng nói thành văn bản", + "learnedFromHeaders": "Học từ các header", + "totalRequests": "Tổng số yêu cầu", + "cloudUnstableNote": "Lưu ý: dịch vụ đám mây không ổn định", + "gamificationAdmin": "Quản trị trò chơi hóa", "monitorAnomaliesAndHealth": "Theo dõi sự bất thường và tình trạng hệ thống", - "flaggedAnomalies": "Điểm bất thường được gắn cờ", + "flaggedAnomalies": "Các bất thường bị gắn cờ", "noAnomaliesDetected": "Không phát hiện bất thường", "apiKey": "Khóa API", - "xpLastHour": "XP (1h)", + "xpLastHour": "XP (1 giờ)", "zScore": "Điểm Z", "tokensCommunityServers": "Máy chủ cộng đồng", "tokensServerNamePlaceholder": "Tên máy chủ", "tokensApiKeyPlaceholder": "Khóa API", - "tokensTokenBalance": "Số dư mã thông báo", - "tokensSendTokens": "Gửi mã thông báo", + "tokensTokenBalance": "Số dư token", + "tokensSendTokens": "Gửi token", "tokensRecipientApiKeyId": "ID khóa API của người nhận", "tokensRecipientApiKeyIdPlaceholder": "Nhập ID khóa API của người nhận", "tokensReasonOptional": "Lý do (tùy chọn)", @@ -678,17 +678,17 @@ "tokensTransactionHistory": "Lịch sử giao dịch", "tokensNoTransactionsYet": "Chưa có giao dịch nào", "tokensInviteCodes": "Mã mời", - "tokensMaxUses": "Sử dụng tối đa", + "tokensMaxUses": "Số lần sử dụng tối đa", "tokensRedeemCode": "Đổi mã", "tokensRedeemCodePlaceholder": "Nhập mã mời", "tokensYourActiveInvites": "Lời mời hoạt động của bạn", - "tierCoverageTitle": "Mức độ bao phủ", + "tierCoverageTitle": "Mức độ bao phủ theo tầng", "tierCoverageSubtitle": "Nhà cung cấp được định cấu hình cho mỗi tầng dự phòng", - "batchDetailCopyId": "Sao chép giấy tờ tùy thân", + "batchDetailCopyId": "Sao chép ID", "batchDetailClose": "Đóng", - "batchDetailEndpoint": "Điểm cuối", - "batchDetailModel": "người mẫu", - "batchDetailWindow": "Cửa sổ", + "batchDetailEndpoint": "Endpoint", + "batchDetailModel": "Mô hình", + "batchDetailWindow": "Khung thời gian", "batchDetailCreated": "Đã tạo", "providerTopologyEmpty": "Chưa có nhà cung cấp nào được kết nối", "badgeToastUnlocked": "Huy hiệu đã được mở khóa!", @@ -697,190 +697,194 @@ "batchListBatchesTable": "Lô", "changelogViewerLoading": "Đang tải nhật ký thay đổi từ GitHub...", "profileLoading": "Đang tải hồ sơ...", - "profileHowToEarn": "Làm thế nào để kiếm được", - "bootstrapBannerDismiss": "Loại bỏ", + "profileHowToEarn": "Cách kiếm điểm", + "bootstrapBannerDismiss": "Bỏ qua", "batchListDeleteBatchTitle": "Xóa lô và các tập tin của nó", "leaderboardYourRank": "Thứ hạng của bạn", "leaderboardLoading": "Đang tải bảng xếp hạng...", - "batchFileDetailCopyId": "Sao chép giấy tờ tùy thân", + "batchFileDetailCopyId": "Sao chép ID", "batchFileDetailClose": "Đóng", "batchFileDetailFailedToLoad": "Không thể tải nội dung tập tin", "batchFilesListSearchPlaceholder": "Tìm kiếm theo ID hoặc tên tập tin…", "batchFilesListFilesTable": "Tập tin", "batchPageLoadingMore": "Đang tải thêm…", - "recommended": "__MISSING__:Recommended", - "batchConceptTitle": "Batch processing", - "batchConceptSubtitle": "Process thousands of requests asynchronously at ~50% of the cost (24h window). Ideal for evaluations, classification, and embeddings.", - "batchConceptHowItWorks": "How it works", - "batchConceptBenefit50pct": "50% discount on input + output tokens", - "batchConceptAsync24h": "Async with a 24h completion window", - "batchConceptUseCases": "Best for bulk classification, evaluations, and embeddings", - "filesConceptTitle": "Batch files", - "filesConceptSubtitle": "JSONL files used by batches: input requests, results, and errors.", - "filesConceptInput": "Input — your JSONL with one request per line", - "filesConceptOutput": "Output — results from completed requests", - "filesConceptError": "Errors — requests that failed", - "filesConceptRetention": "Retention: 30 days by default (29 days on Anthropic)", - "wizardTitle": "New batch", - "wizardClose": "Close", - "wizardNext": "Next", - "wizardBack": "Back", - "wizardCancel": "Cancel", - "wizardCreate": "Create batch", - "wizardCreating": "Creating…", - "wizardStep1Destination": "Destination", - "wizardStep2Input": "Input", - "wizardStep3Validate": "Validate", - "wizardStep4Cost": "Cost & create", - "wizardProviderLabel": "Provider", + "recommended": "Khuyến nghị", + "batchConceptTitle": "Xử lý theo lô", + "batchConceptSubtitle": "Xử lý hàng nghìn yêu cầu một cách bất đồng bộ với chi phí chỉ khoảng 50% (khung thời gian 24 giờ). Lý tưởng cho việc đánh giá, phân loại và embedding.", + "batchConceptHowItWorks": "Cách hoạt động", + "batchConceptBenefit50pct": "Giảm 50% cho token đầu vào và đầu ra", + "batchConceptAsync24h": "Bất đồng bộ với khung thời gian hoàn thành 24 giờ", + "batchConceptUseCases": "Phù hợp nhất cho phân loại số lượng lớn, đánh giá và embedding", + "filesConceptTitle": "Tập tin lô", + "filesConceptSubtitle": "Các tập tin JSONL được sử dụng bởi các lô: yêu cầu đầu vào, kết quả và lỗi.", + "filesConceptInput": "Đầu vào — tập tin JSONL của bạn với một yêu cầu trên mỗi dòng", + "filesConceptOutput": "Đầu ra — kết quả từ các yêu cầu đã hoàn thành", + "filesConceptError": "Lỗi — các yêu cầu không thành công", + "filesConceptRetention": "Thời gian lưu trữ: 30 ngày theo mặc định (29 ngày trên Anthropic)", + "wizardTitle": "Lô mới", + "wizardClose": "Đóng", + "wizardNext": "Tiếp theo", + "wizardBack": "Quay lại", + "wizardCancel": "Hủy", + "wizardCreate": "Tạo lô", + "wizardCreating": "Đang tạo…", + "wizardStep1Destination": "Đích đến", + "wizardStep2Input": "Đầu vào", + "wizardStep3Validate": "Kiểm tra", + "wizardStep4Cost": "Chi phí & tạo", + "wizardProviderLabel": "Nhà cung cấp", "wizardEndpointLabel": "Endpoint", - "wizardModelLabel": "Model", + "wizardModelLabel": "Mô hình", "wizardInputKindJsonl": "JSONL", - "wizardInputKindCsv": "CSV (we'll convert)", - "wizardDropOrPick": "Drop a file or click to pick", - "wizardCsvMappingTitle": "Map CSV columns → request fields", - "wizardCsvMappingAddField": "Add field", - "wizardValidationOk": "All lines valid", - "wizardValidationErrors": "Validation errors", - "wizardValidationPreview": "Preview (first 5 requests)", - "wizardValidationSamplingNote": "File is large — validated by sampling (first 1000 + last 100 lines). Full validation runs server-side.", - "wizardCostSync": "Sync cost", - "wizardCostBatch": "Batch cost (-50%)", - "wizardCostSavings": "Savings", - "wizardCostEstimatedNotice": "Estimated cost — real billing may vary.", - "wizardErrorUpload": "Failed to upload file. Try again.", - "wizardErrorCreate": "Failed to create batch. Try again.", - "wizardEmptyProviders": "Connect a provider with batch support (OpenAI, Anthropic, or Gemini) to create a batch.", - "uploadModalTitle": "Upload batch file", - "uploadModalDropOrPick": "Drop a .jsonl file or click to pick", - "uploadModalUpload": "Upload", - "uploadModalCancel": "Cancel", - "uploadModalError": "Upload failed. Try again.", - "uploadModalSuccess": "Uploaded", - "uploadModalSizeLimit": "Max 512 MB", - "batchListNewButton": "New batch", - "batchListAutoRefresh": "Auto-refresh 30s", - "batchListCostColumn": "Cost", - "batchActionCancel": "Cancel", - "batchActionDownloadOutput": "Download output", - "batchActionDownloadErrors": "Download errors", - "batchActionRetry": "Retry failed", - "batchActionRetryConfirm": "Retry {n} failed request(s)? Final cost depends on actual tokens consumed.", - "expirationBadgeCritical": "Critical", - "expirationBadgeWarning": "Soon", - "expirationBadgeNormal": "Pending", - "expirationBadgeExpired": "Expired", - "filesListUploadButton": "Upload", - "filesListUsedByColumn": "Used by", - "filesListUsedByNone": "None", - "filesListDelete": "Delete", - "filesListDownload": "Download", - "batchDetailActionCancel": "Cancel batch", - "batchDetailActionRetry": "Retry failed requests", - "batchDetailCancelling": "Cancelling…", - "batchDetailRetrying": "Preparing retry…", - "batchDetailCancelConfirm": "Cancel this batch? In-progress requests will stop.", - "batchActionCancelError": "Failed to cancel batch. Try again.", - "batchActionRetryError": "Failed to retry failed requests. Try again.", - "batchConceptRetentionNote": "Results and error files are retained for 30 days (Anthropic: 29 days)", - "filesListUsedByRoleInput": "input", - "filesListUsedByRoleOutput": "output", - "filesListUsedByRoleError": "error", - "batchListProgressPartial": "(partial)", - "filesListSizeColumn": "Size", - "batchListProviderColumn": "Provider", + "wizardInputKindCsv": "CSV (chúng tôi sẽ chuyển đổi)", + "wizardDropOrPick": "Kéo thả tập tin hoặc nhấp để chọn", + "wizardCsvMappingTitle": "Ánh xạ các cột CSV → các trường trong yêu cầu", + "wizardCsvMappingAddField": "Thêm trường", + "wizardValidationOk": "Tất cả các dòng hợp lệ", + "wizardValidationErrors": "Lỗi kiểm tra tính hợp lệ", + "wizardValidationPreview": "Xem trước (5 yêu cầu đầu tiên)", + "wizardValidationSamplingNote": "Tập tin quá lớn — được kiểm tra bằng phương pháp lấy mẫu (1.000 dòng đầu tiên + 100 dòng cuối cùng). Việc kiểm tra đầy đủ được thực hiện phía máy chủ.", + "wizardCostSync": "Chi phí đồng bộ", + "wizardCostBatch": "Chi phí theo lô (-50%)", + "wizardCostSavings": "Tiết kiệm", + "wizardCostEstimatedNotice": "Chi phí ước tính — chi phí thanh toán thực tế có thể khác.", + "wizardErrorUpload": "Tải lên tập tin không thành công. Vui lòng thử lại.", + "wizardErrorCreate": "Tạo lô không thành công. Vui lòng thử lại.", + "wizardEmptyProviders": "Kết nối một nhà cung cấp hỗ trợ xử lý theo lô (OpenAI, Anthropic hoặc Gemini) để tạo lô.", + "uploadModalTitle": "Tải lên tập tin lô", + "uploadModalDropOrPick": "Kéo thả tập tin .jsonl hoặc nhấp để chọn", + "uploadModalUpload": "Tải lên", + "uploadModalCancel": "Hủy", + "uploadModalError": "Tải lên không thành công. Vui lòng thử lại.", + "uploadModalSuccess": "Đã tải lên", + "uploadModalSizeLimit": "Tối đa 512 MB", + "batchListNewButton": "Lô mới", + "batchListAutoRefresh": "Tự động làm mới 30 giây", + "batchListCostColumn": "Chi phí", + "batchActionCancel": "Hủy", + "batchActionDownloadOutput": "Tải xuống kết quả đầu ra", + "batchActionDownloadErrors": "Tải xuống lỗi", + "batchActionRetry": "Thử lại các yêu cầu thất bại", + "batchActionRetryConfirm": "Thử lại {n} yêu cầu thất bại? Chi phí cuối cùng phụ thuộc vào số token thực tế đã sử dụng.", + "expirationBadgeCritical": "Nghiêm trọng", + "expirationBadgeWarning": "Sắp hết hạn", + "expirationBadgeNormal": "Đang chờ", + "expirationBadgeExpired": "Đã hết hạn", + "filesListUploadButton": "Tải lên", + "filesListUsedByColumn": "Được sử dụng bởi", + "filesListUsedByNone": "Không có", + "filesListDelete": "Xóa", + "filesListDownload": "Tải xuống", + "batchDetailActionCancel": "Hủy lô", + "batchDetailActionRetry": "Thử lại các yêu cầu thất bại", + "batchDetailCancelling": "Đang hủy…", + "batchDetailRetrying": "Đang chuẩn bị thử lại…", + "batchDetailCancelConfirm": "Hủy lô này? Các yêu cầu đang xử lý sẽ ngừng lại.", + "batchActionCancelError": "Không thể hủy lô. Vui lòng thử lại.", + "batchActionRetryError": "Không thể thử lại các yêu cầu thất bại. Vui lòng thử lại.", + "batchConceptRetentionNote": "Kết quả và các tệp lỗi được lưu giữ trong 30 ngày (Anthropic: 29 ngày)", + "filesListUsedByRoleInput": "đầu vào", + "filesListUsedByRoleOutput": "đầu ra", + "filesListUsedByRoleError": "lỗi", + "batchListProgressPartial": "(một phần)", + "filesListSizeColumn": "Kích thước", + "batchListProviderColumn": "Nhà cung cấp", "batchListProviderUnknown": "—", - "batchListBatchCreated": "Batch {id} created — refreshing list…", - "batchListBatchCreatedDismiss": "Dismiss", - "batchListRefreshing": "Refreshing…", - "batchListRefresh": "Refresh", - "uploadFileModalRemove": "Remove", - "uploadFileModalUploading": "Uploading…", - "wizardInputReading": "Reading file…", - "wizardInputReady": "Ready", - "wizardInputLargeFileLabel": "Large file — sampling validation", - "wizardInputCsvJsonlReady": "JSONL generated — ready to validate.", - "wizardInputLargeFileWarning": "Large file detected — validation runs by sampling (first 5 MB + last 100 KB). Full validation happens server-side.", - "wizardCostWindow24h": "24h completion window", - "wizardValidationFieldsOk": "required fields valid", - "batchListProviderOther": "Other", - "batchListTitle": "Batches", - "batchListCount": "{count} batches", - "batchListRemovingCompleted": "Removing…", - "batchListRemoveCompleted": "Remove completed", - "batchListTableStatus": "Status", + "batchListBatchCreated": "Đã tạo lô {id} — đang làm mới danh sách…", + "batchListBatchCreatedDismiss": "Đóng", + "batchListRefreshing": "Đang làm mới…", + "batchListRefresh": "Làm mới", + "uploadFileModalRemove": "Xóa", + "uploadFileModalUploading": "Đang tải lên…", + "wizardInputReading": "Đang đọc tệp…", + "wizardInputReady": "Sẵn sàng", + "wizardInputLargeFileLabel": "Tệp lớn — xác thực bằng lấy mẫu", + "wizardInputCsvJsonlReady": "Đã tạo JSONL — sẵn sàng để xác thực.", + "wizardInputLargeFileWarning": "Đã phát hiện tệp lớn — quá trình xác thực chạy bằng cách lấy mẫu (5 MB đầu + 100 KB cuối). Việc xác thực đầy đủ diễn ra ở phía máy chủ.", + "wizardCostWindow24h": "Khung thời gian hoàn thành 24 giờ", + "wizardValidationFieldsOk": "các trường bắt buộc hợp lệ", + "batchListProviderOther": "Khác", + "batchListTitle": "Lô", + "batchListCount": "{count} lô", + "batchListRemovingCompleted": "Đang xóa…", + "batchListRemoveCompleted": "Xóa các mục đã hoàn thành", + "batchListTableStatus": "Trạng thái", "batchListTableId": "ID", "batchListTableEndpoint": "Endpoint", - "batchListTableModel": "Model", - "batchListTableProgress": "Progress", - "batchListTableCreated": "Created", - "batchListTableExpires": "Expires", - "batchListLoading": "Loading…", - "batchListEmpty": "No batches found", - "batchListValidating": "Validating…", - "batchStatusAll": "All statuses", - "batchStatusInProgress": "In progress", - "batchStatusValidating": "Validating", - "batchStatusFinalizing": "Finalizing", - "batchStatusCompleted": "Completed", - "batchStatusFailed": "Failed", - "batchStatusCancelled": "Cancelled", - "batchStatusCancelling": "Cancelling", - "batchStatusExpired": "Expired", - "batchStatusCompletedWithFailures": "completed with failures", - "batchStatusInProgressWithFailures": "in progress (with failures)", - "batchStatusFinalizingWithFailures": "finalizing (with failures)", - "batchStatusCancelledWithFailures": "cancelled with failures", - "batchStatusExpiredWithFailures": "expired (partial)", - "wizardCostEstimating": "Estimating cost…", - "wizardCostRequests": "Requests", - "wizardCostInputTok": "input tok", - "wizardCostOutputTok": "output tok", - "wizardCostWindow": "Window", - "wizardDestinationSelectProvider": "Select a provider…", - "wizardDestinationSelectModel": "Select a model…", - "wizardDestinationConnectProvider": "Connect a provider" + "batchListTableModel": "Mô hình", + "batchListTableProgress": "Tiến trình", + "batchListTableCreated": "Đã tạo", + "batchListTableExpires": "Hết hạn", + "batchListLoading": "Đang tải…", + "batchListEmpty": "Không tìm thấy lô nào", + "batchListValidating": "Đang xác thực…", + "batchStatusAll": "Tất cả trạng thái", + "batchStatusInProgress": "Đang xử lý", + "batchStatusValidating": "Đang xác thực", + "batchStatusFinalizing": "Đang hoàn tất", + "batchStatusCompleted": "Đã hoàn thành", + "batchStatusFailed": "Thất bại", + "batchStatusCancelled": "Đã hủy", + "batchStatusCancelling": "Đang hủy", + "batchStatusExpired": "Đã hết hạn", + "batchStatusCompletedWithFailures": "hoàn thành kèm lỗi", + "batchStatusInProgressWithFailures": "đang xử lý (có lỗi)", + "batchStatusFinalizingWithFailures": "đang hoàn tất (có lỗi)", + "batchStatusCancelledWithFailures": "đã hủy kèm lỗi", + "batchStatusExpiredWithFailures": "đã hết hạn (một phần)", + "wizardCostEstimating": "Đang ước tính chi phí…", + "wizardCostRequests": "Yêu cầu", + "wizardCostInputTok": "token đầu vào", + "wizardCostOutputTok": "token đầu ra", + "wizardCostWindow": "Khung thời gian", + "wizardDestinationSelectProvider": "Chọn một nhà cung cấp…", + "wizardDestinationSelectModel": "Chọn một mô hình…", + "wizardDestinationConnectProvider": "Kết nối một nhà cung cấp", + "manualConfig": "Manual config", + "unknownProvider": "Unknown provider", + "queueDepth": "Queue Depth", + "understand": "I understand" }, "sidebar": { "home": "Trang chủ", "dashboard": "Trang tổng quan", "providers": "Nhà cung cấp", "combos": "Combo", - "usage": "Cách sử dụng", + "usage": "Mức sử dụng", "analytics": "Phân tích", "costs": "Chi phí", - "health": "sức khỏe", + "health": "Tình trạng", "proxy": "Proxy", "limits": "Giới hạn & hạn ngạch", "cliTools": "Công cụ CLI", - "media": "Phương tiện", + "media": "Đa phương tiện", "settings": "Cài đặt", - "translator": "Người phiên dịch", - "playground": "Playground", - "searchTools": "Search Tools", + "translator": "Trình dịch", + "playground": "Khu thử nghiệm", + "searchTools": "Công cụ tìm kiếm", "agents": "Tác nhân", - "cloudAgents": "Đại lý đám mây", - "memory": "Memory", - "skills": "Skills", + "cloudAgents": "Cloud Agents", + "memory": "Bộ nhớ", + "skills": "Kỹ năng", "omniSkills": "OmniSkills", - "agentSkills": "Kỹ năng đại lý", + "agentSkills": "AgentSkills", "docs": "Tài liệu", - "issues": "vấn đề", + "issues": "Vấn đề", "endpoints": "Điểm cuối", "endpointsSubtitle": "URL kết nối AI của bạn", - "apiManager": "Trình quản lý API", + "apiManager": "Khóa API", "apiManagerSubtitle": "Quản lý khóa API và quyền truy cập", - "embeddedServices": "Dịch Vụ Nhúng", + "embeddedServices": "Dịch vụ nhúng", "embeddedServicesSubtitle": "Quản lý các dịch vụ proxy cục bộ", "logs": "Nhật ký", "webhooks": "Webhook", "webhooksSubtitle": "Nhận thông báo về các sự kiện", - "combosSubtitle": "Nhóm nhà cung cấp chuyển đổi dự phòng", + "combosSubtitle": "Nhóm các nhà cung cấp để chuyển đổi dự phòng", "batchSubtitle": "Xử lý nhiều yêu cầu", - "contextCavemanSubtitle": "Nén nhanh chóng", + "contextCavemanSubtitle": "Nén prompt", "contextRtkSubtitle": "Lọc đầu ra", "auditLog": "Nhật ký kiểm tra", - "shutdown": "Tắt máy", + "shutdown": "Tắt", "restart": "Khởi động lại", "shutdownConfirm": "Tắt OmniRoute?", "restartConfirm": "Khởi động lại OmniRoute?", @@ -888,479 +892,596 @@ "debug": "Gỡ lỗi", "system": "Hệ thống", "help": "Trợ giúp", - "primarySection": "Main", + "primarySection": "Mục chính", "cliSection": "CLI", - "debugSection": "Debug", - "systemSection": "System", - "helpSection": "Help", + "debugSection": "Gỡ lỗi", + "systemSection": "Hệ thống", + "helpSection": "Trợ giúp", "serverDisconnected": "Máy chủ bị ngắt kết nối", "serverDisconnectedMsg": "Máy chủ proxy đã bị dừng hoặc đang khởi động lại.", "expandSidebar": "Mở rộng thanh bên", "collapseSidebar": "Thu gọn thanh bên", - "themes": "Themes", - "presetColors": "Popular colors", - "createTheme": "Create theme", - "chooseColor": "Pick one color", - "themeCoral": "Coral", - "themeBlue": "Blue", - "themeRed": "Red", - "themeGreen": "Green", - "themeViolet": "Violet", - "themeOrange": "Orange", - "themeCyan": "Cyan", + "themes": "Giao diện", + "presetColors": "Màu phổ biến", + "createTheme": "Tạo giao diện", + "chooseColor": "Chọn một màu", + "themeCoral": "San hô", + "themeBlue": "Xanh dương", + "themeRed": "Đỏ", + "themeGreen": "Xanh lá", + "themeViolet": "Tím", + "themeOrange": "Cam", + "themeCyan": "Xanh lơ", "cliToolsShort": "Công cụ", "cache": "Cache", "cacheShort": "Cache", - "batch": "Batch Jobs", - "themeSystem": "Theme System", - "whitelabelingDesc": "Whitelabeling Desc", - "switchThemes": "Switch Themes", - "themeAccentDesc": "Theme Accent Desc", - "uploadFavicon": "Upload Favicon", - "themeDark": "Theme Dark", - "customLogoDesc": "Custom Logo Desc", - "sidebarVisibilityToggle": "Sidebar Visibility Toggle", - "themeAccent": "Theme Accent", - "resetFavicon": "Reset Favicon", - "whitelabeling": "Whitelabeling", - "darkMode": "Dark Mode", - "uploadLogo": "Upload Logo", - "themeLight": "Theme Light", - "appName": "App Name", - "appNameDesc": "App Name Desc", - "resetLogo": "Reset Logo", - "customFavicon": "Custom Favicon", - "hideHealthLogs": "Hide Health Logs", - "customLogo": "Custom Logo", - "appearance": "Appearance", - "themeSelectionAria": "Theme Selection Aria", - "themeCreate": "Theme Create", - "customFaviconDesc": "Custom Favicon Desc", - "logoPreview": "Logo Preview", - "themeCustom": "Theme Custom", - "hideHealthLogsDesc": "Hide Health Logs Desc", - "faviconPreview": "Favicon Preview", - "changelog": "Changelog", - "contextSection": "Context & Cache", + "batch": "Tác vụ hàng loạt", + "themeSystem": "Giao diện theo hệ thống", + "whitelabelingDesc": "Mô tả về gắn nhãn trắng", + "switchThemes": "Chuyển đổi giao diện", + "themeAccentDesc": "Mô tả màu nhấn của giao diện", + "uploadFavicon": "Tải lên favicon", + "themeDark": "Giao diện tối", + "customLogoDesc": "Mô tả logo tùy chỉnh", + "sidebarVisibilityToggle": "Bật/tắt hiển thị thanh bên", + "themeAccent": "Màu nhấn giao diện", + "resetFavicon": "Đặt lại favicon", + "whitelabeling": "Gắn nhãn trắng", + "darkMode": "Chế độ tối", + "uploadLogo": "Tải lên logo", + "themeLight": "Giao diện sáng", + "appName": "Tên ứng dụng", + "appNameDesc": "Mô tả tên ứng dụng", + "resetLogo": "Đặt lại logo", + "customFavicon": "Favicon tùy chỉnh", + "hideHealthLogs": "Ẩn nhật ký tình trạng", + "customLogo": "Logo tùy chỉnh", + "appearance": "Giao diện hiển thị", + "themeSelectionAria": "Nhãn ARIA để chọn giao diện", + "themeCreate": "Tạo giao diện", + "customFaviconDesc": "Mô tả favicon tùy chỉnh", + "logoPreview": "Xem trước logo", + "themeCustom": "Giao diện tùy chỉnh", + "hideHealthLogsDesc": "Mô tả ẩn nhật ký tình trạng", + "faviconPreview": "Xem trước favicon", + "changelog": "Lịch sử thay đổi", + "contextSection": "Ngữ cảnh & Cache", "contextCaveman": "Caveman", "contextRtk": "RTK", - "contextCombos": "Engine Combos", + "contextCombos": "Tổ hợp công cụ", "contextLite": "Lite", "contextAggressive": "Aggressive", "contextUltra": "Ultra", "contextOmniglyph": "OmniGlyph", - "contextSettings": "Compression Settings", + "contextSettings": "Cài đặt nén", "contextHeadroom": "Headroom", "contextSessionDedup": "Session Dedup", "contextCcr": "CCR", "contextLlmlingua": "LLMLingua", "combosLive": "Combo Studio", "compressionStudio": "Compression Studio", - "routingSection": "Routing", - "protocolsSection": "Protocols", - "agentsAiSection": "Agents & AI", - "cacheContextSection": "Cache & Context", - "analyticsSection": "Analytics", - "costsSection": "Costs", - "monitoringSection": "Monitoring", - "auditSecuritySection": "Audit & Security", - "devtoolsSection": "Dev Tools", - "configurationSection": "Configuration", - "aiFeaturesSection": "AI Features", - "mcp": "MCP", - "a2a": "A2A", - "apiEndpoints": "API Endpoints", - "batchFiles": "Files", - "analyticsEvals": "Evals", - "analyticsSearch": "Search", - "analyticsUtilization": "Utilization", - "analyticsComboHealth": "Combo Health", - "analyticsCompression": "Compression", - "costsBudget": "Budget", - "costsQuotaShare": "Quota Sharing", - "costsPricing": "Pricing", - "logsProxy": "Proxy Logs", - "logsConsole": "Console", - "logsActivity": "Activity", - "auditMcp": "MCP Audit", + "routingSection": "Định tuyến", + "protocolsSection": "Giao thức", + "agentsAiSection": "Tác nhân & AI", + "cacheContextSection": "Cache & Ngữ cảnh", + "analyticsSection": "Phân tích", + "costsSection": "Chi phí", + "monitoringSection": "Giám sát", + "auditSecuritySection": "Kiểm toán & Bảo mật", + "devtoolsSection": "Công cụ phát triển", + "configurationSection": "Cấu hình", + "aiFeaturesSection": "Tính năng AI", + "mcp": "Máy chủ MCP", + "a2a": "Máy chủ A2A", + "apiEndpoints": "Các endpoint API", + "batchFiles": "Tệp", + "analyticsEvals": "Đánh giá", + "analyticsSearch": "Tìm kiếm", + "analyticsUtilization": "Mức sử dụng", + "analyticsComboHealth": "Tình trạng tổ hợp", + "analyticsCompression": "Nén dữ liệu", + "costsBudget": "Ngân sách", + "costsQuotaShare": "Chia sẻ hạn mức", + "costsPricing": "Định giá", + "logsProxy": "Nhật ký proxy", + "logsConsole": "Bảng điều khiển", + "logsActivity": "Hoạt động", + "auditMcp": "Kiểm toán MCP", "auditA2a": "Kiểm toán A2A", - "settingsGeneral": "General", - "settingsAppearance": "Appearance", - "settingsAi": "AI Settings", - "settingsSecurity": "Security", + "settingsGeneral": "Lưu trữ", + "settingsAppearance": "Giao diện", + "settingsAi": "Cài đặt AI", + "settingsSecurity": "Bảo mật", "settingsFeatureFlags": "Cờ tính năng", - "settingsAuthz": "__MISSING__:Authz", - "settingsRouting": "Routing", - "settingsResilience": "Resilience", - "settingsAdvanced": "Advanced", + "settingsAuthz": "Phân quyền", + "settingsRouting": "Định tuyến", + "settingsResilience": "Khả năng phục hồi", + "settingsAdvanced": "Nâng cao", "omniProxySection": "OmniProxy", - "quotaTracker": "Provider Quota", - "providerQuota": "Provider Quota", - "runtime": "Runtime", - "consoleLogs": "Console Logs", - "globalRouting": "Global Routing", + "quotaTracker": "Hạn mức của nhà cung cấp", + "providerQuota": "Hạn mức của nhà cung cấp", + "runtime": "Thời gian chạy", + "consoleLogs": "Nhật ký bảng điều khiển", + "globalRouting": "Định tuyến toàn cục", "mitmProxy": "MITM Proxy", "oneProxy": "1Proxy", - "agenticFeaturesSection": "Agentic Features", - "otherFeaturesSection": "Other Features", - "compressionContextGroup": "Compression Context", - "gamificationGroup": "Gamification", - "toolsGroup": "Tools", - "integrationsGroup": "Integrations", + "agenticFeaturesSection": "Tính năng tác tử", + "otherFeaturesSection": "Tính năng khác", + "compressionContextGroup": "Nén ngữ cảnh", + "gamificationGroup": "Trò chơi hóa", + "toolsGroup": "Công cụ", + "integrationsGroup": "Tích hợp", "proxyGroup": "Proxy", - "costsParametersGroup": "Costs Parameters", - "auditGroup": "Audit", - "batchGroup": "Batch", - "homeSubtitle": "Dashboard overview", - "providersSubtitle": "Manage AI providers", - "quotaTrackerSubtitle": "Track usage limits", - "providerQuotaSubtitle": "Track provider usage limits", - "runtimeSubtitle": "Realtime resilience & sessions", - "contextCombosSubtitle": "Combine compression engines", - "cliToolsSubtitle": "Configure CLI runtimes", - "agentsSubtitle": "Manage local agents", - "cloudAgentsSubtitle": "Manage cloud-based agents", - "apiEndpointsSubtitle": "Expose custom endpoints", - "proxySubtitle": "HTTP proxy settings", - "mitmProxySubtitle": "MITM interception", - "oneProxySubtitle": "Public proxy gateway", - "leaderboard": "Leaderboard", - "profile": "Profile", - "tokens": "Tokens", - "leaderboardSubtitle": "Rankings and achievements", - "profileSubtitle": "Account and preferences", - "tokensSubtitle": "Token usage and budgets", - "usageSubtitle": "Traffic and usage stats", - "analyticsComboHealthSubtitle": "Combo target reliability", - "analyticsUtilizationSubtitle": "Provider utilization", - "costsSubtitle": "Spend breakdown", - "cacheSubtitle": "Cache hit rates", - "analyticsCompressionSubtitle": "Token savings stats", - "analyticsSearchSubtitle": "Search tool analytics", - "analyticsEvalsSubtitle": "Eval suite results", - "logsSubtitle": "Application logs", - "logsProxySubtitle": "Proxy traffic logs", - "consoleLogsSubtitle": "Console output", - "logsActivitySubtitle": "User activity log", - "healthSubtitle": "System health check", - "costsPricingSubtitle": "Per-model pricing rules", - "costsBudgetSubtitle": "Budget limits", - "costsQuotaShareSubtitle": "Share provider quotas across keys", - "auditLogSubtitle": "Authorization audit", - "auditMcpSubtitle": "MCP server audit", - "auditA2aSubtitle": "A2A protocol audit", - "translatorSubtitle": "Format conversion", - "playgroundSubtitle": "Test prompts live", - "searchToolsSubtitle": "Search tool registry", - "memorySubtitle": "Persistent agent memory", - "omniSkillsSubtitle": "Sandbox skill registry", - "agentSkillsSubtitle": "A2A skill registry", - "mcpSubtitle": "MCP server controls", - "a2aSubtitle": "A2A protocol server", - "mediaSubtitle": "Cached media files", - "batchFilesSubtitle": "Batch input/output files", - "settingsSubtitle": "All settings", - "settingsGeneralSubtitle": "App basics", - "settingsAppearanceSubtitle": "Theme and layout", - "settingsAiSubtitle": "AI behavior defaults", - "globalRoutingSubtitle": "Global routing rules", - "settingsResilienceSubtitle": "Retries and breakers", - "settingsAdvancedSubtitle": "Power user options", - "settingsSecuritySubtitle": "Auth and encryption", - "settingsFeatureFlagsSubtitle": "Chuyển đổi khả năng của hệ thống", - "settingsSidebar": "Sidebar", - "settingsSidebarSubtitle": "Customize sidebar layout", - "settingsAuthzSubtitle": "__MISSING__:Route inventory and bypass policy", - "docsSubtitle": "Documentation", - "issuesSubtitle": "Report a bug", - "changelogSubtitle": "Release notes" + "costsParametersGroup": "Tham số chi phí", + "auditGroup": "Kiểm toán", + "batchGroup": "Xử lý theo lô", + "homeSubtitle": "Tổng quan bảng điều khiển", + "providersSubtitle": "Quản lý nhà cung cấp AI", + "quotaTrackerSubtitle": "Theo dõi giới hạn mức sử dụng", + "providerQuotaSubtitle": "Theo dõi giới hạn mức sử dụng của nhà cung cấp", + "runtimeSubtitle": "Khả năng phục hồi thời gian thực & phiên làm việc", + "contextCombosSubtitle": "Kết hợp các bộ máy nén", + "cliToolsSubtitle": "Cấu hình môi trường thời gian chạy CLI", + "agentsSubtitle": "Quản lý tác tử cục bộ", + "cloudAgentsSubtitle": "Quản lý tác tử trên nền tảng đám mây", + "apiEndpointsSubtitle": "Công khai các endpoint tùy chỉnh", + "proxySubtitle": "Cài đặt HTTP proxy", + "mitmProxySubtitle": "Chặn bắt MITM", + "oneProxySubtitle": "Cổng proxy công khai", + "leaderboard": "Bảng xếp hạng", + "profile": "Hồ sơ", + "tokens": "Token", + "leaderboardSubtitle": "Xếp hạng và thành tích", + "profileSubtitle": "Tài khoản và tùy chọn", + "tokensSubtitle": "Mức sử dụng và ngân sách token", + "usageSubtitle": "Thống kê lưu lượng và mức sử dụng", + "analyticsComboHealthSubtitle": "Độ tin cậy của combo mục tiêu", + "analyticsUtilizationSubtitle": "Mức sử dụng nhà cung cấp", + "costsSubtitle": "Phân tích chi tiêu", + "cacheSubtitle": "Tỷ lệ trúng cache", + "analyticsCompressionSubtitle": "Thống kê tiết kiệm token", + "analyticsSearchSubtitle": "Phân tích công cụ tìm kiếm", + "analyticsEvalsSubtitle": "Kết quả bộ đánh giá", + "logsSubtitle": "Nhật ký ứng dụng", + "logsProxySubtitle": "Nhật ký lưu lượng proxy", + "consoleLogsSubtitle": "Đầu ra bảng điều khiển", + "logsActivitySubtitle": "Nhật ký hoạt động người dùng", + "healthSubtitle": "Kiểm tra tình trạng hệ thống", + "costsPricingSubtitle": "Quy tắc định giá theo từng mô hình", + "costsBudgetSubtitle": "Giới hạn ngân sách", + "costsQuotaShareSubtitle": "Chia sẻ hạn ngạch của nhà cung cấp giữa các khóa", + "auditLogSubtitle": "Kiểm toán phân quyền", + "auditMcpSubtitle": "Kiểm toán máy chủ MCP", + "auditA2aSubtitle": "Kiểm toán giao thức A2A", + "translatorSubtitle": "Chuyển đổi định dạng", + "playgroundSubtitle": "Thử nghiệm prompt trực tiếp", + "searchToolsSubtitle": "Danh mục công cụ tìm kiếm", + "memorySubtitle": "Bộ nhớ tác tử lâu dài", + "omniSkillsSubtitle": "Danh mục kỹ năng sandbox", + "agentSkillsSubtitle": "Danh mục kỹ năng A2A", + "mcpSubtitle": "Điều khiển máy chủ MCP", + "a2aSubtitle": "Máy chủ giao thức A2A", + "mediaSubtitle": "Tệp phương tiện được lưu trong cache", + "batchFilesSubtitle": "Tệp đầu vào/đầu ra theo lô", + "settingsSubtitle": "Tất cả cài đặt", + "settingsGeneralSubtitle": "Cơ sở dữ liệu và bản sao lưu", + "settingsAppearanceSubtitle": "Giao diện và bố cục", + "settingsAiSubtitle": "Mặc định hành vi AI", + "globalRoutingSubtitle": "Quy tắc định tuyến toàn cục", + "settingsResilienceSubtitle": "Thử lại và ngắt mạch", + "settingsAdvancedSubtitle": "Tùy chọn cho người dùng nâng cao", + "settingsSecuritySubtitle": "Xác thực và mã hóa", + "settingsFeatureFlagsSubtitle": "Chuyển đổi các khả năng của hệ thống", + "settingsSidebar": "Thanh bên", + "settingsSidebarSubtitle": "Tùy chỉnh bố cục thanh bên", + "settingsAuthzSubtitle": "Kiểm kê định tuyến và chính sách bỏ qua", + "docsSubtitle": "Tài liệu", + "issuesSubtitle": "Báo lỗi", + "changelogSubtitle": "Ghi chú phát hành", + "chaosConfig": "Chaos Mode", + "plugins": "Plugins", + "costsFreeTiers": "Free-Tier Budget", + "costsFreeTiersSubtitle": "Monthly free-token allowances", + "freeProviderRankings": "Free Provider Rankings", + "freeProviderRankingsSubtitle": "Best free providers ranked by model ELO scores", + "settingsAccessTokens": "Access Tokens", + "modelLockout": "Model Lockout", + "providerStats": "Provider Stats", + "providerStatsSubtitle": "Latency and performance metrics", + "pluginsSubtitle": "Plugin marketplace & installs", + "settingsAccessTokensSubtitle": "Scoped CLI tokens for remote mode", + "costsQuotaPlans": "Plans & Quotas", + "costsQuotaPlansSubtitle": "Configure plans by provider", + "activity": "Activity", + "activitySubtitle": "Friendly feed of recent events", + "logsGroup": "Logs", + "systemGroup": "System", + "costsOverview": "Overview", + "costsOverviewSubtitle": "Consolidated cost analysis", + "agentBridge": "Agent Bridge", + "agentBridgeSubtitle": "Intercept IDE agent traffic", + "trafficInspector": "Traffic Inspector", + "trafficInspectorSubtitle": "Monitor LLM calls + debug any HTTPS traffic", + "cliCode": "CLI Code", + "cliCodeSubtitle": "Code tools pointing to OmniRoute", + "cliAgents": "CLI Agents", + "cliAgentsSubtitle": "Autonomous CLI agents", + "acpAgents": "ACP Agents", + "acpAgentsSubtitle": "CLIs spawned by OmniRoute", + "skipToContent": "Skip to content", + "unpinSection": "Unpin section", + "pinSectionOpen": "Pin section open", + "reloadPage": "Reload Page", + "dragReorderSection": "Drag to reorder section", + "dragReorderItem": "Drag to reorder", + "cannotHide": "This item cannot be hidden", + "alwaysVisible": "Always visible", + "groupSeparatorLabel": "Separator", + "discovery": "Discovery", + "discoverySubtitle": "Scan providers for free access" }, "webhooks": { "title": "Webhook", - "description": "Định cấu hình lệnh gọi lại HTTP cho các sự kiện hệ thống.", - "configuredWebhooks": "Webhooks được định cấu hình", - "configuredWebhooksDesc": "Quản lý điểm cuối phân phối, sự kiện đã đăng ký, trạng thái và gửi thử nghiệm.", + "description": "Định cấu hình các lệnh gọi lại HTTP cho các sự kiện hệ thống.", + "configuredWebhooks": "Webhook đã được định cấu hình", + "configuredWebhooksDesc": "Quản lý điểm cuối phân phối, các sự kiện đã đăng ký, trạng thái và gửi thử nghiệm.", "addWebhook": "Thêm Webhook", "editWebhook": "Chỉnh sửa Webhook", "name": "Tên", - "namePlaceholder": "Giám sát sản xuất", + "namePlaceholder": "Giám sát môi trường sản xuất", "unnamedWebhook": "Webhook chưa được đặt tên", "url": "URL điểm cuối", "events": "Sự kiện", "allEvents": "Tất cả sự kiện", - "secret": "bí mật", - "secretPlaceholder": "Để trống để tự động tạo bí mật", - "secretEditPlaceholder": "Để trống để giữ bí mật hiện tại", + "secret": "Khóa bí mật", + "secretPlaceholder": "Để trống để tự động tạo khóa bí mật", + "secretEditPlaceholder": "Để trống để giữ khóa bí mật hiện tại", "status": "Trạng thái", "active": "Đang hoạt động", "inactive": "Không hoạt động", "errored": "Đã xảy ra lỗi", "total": "Tổng cộng", "lastTriggered": "Kích hoạt lần cuối", - "actions": "hành động", + "actions": "Hành động", "enabled": "Đã bật", - "enabledDesc": "Webhook bị vô hiệu hóa vẫn được lưu nhưng không nhận được hàng gửi.", + "enabledDesc": "Webhook bị vô hiệu hóa vẫn được lưu nhưng không nhận được các lượt gửi.", "refresh": "Làm mới", "loading": "Đang tải webhook...", - "never": "không bao giờ", - "failureCount": "{count, plural, =0 {no failures} one {# failure} other {# failures}}", - "testWebhook": "Gửi bài kiểm tra", - "testSuccess": "Kiểm tra webhook đã được gửi thành công.", - "testFailed": "Kiểm tra webhook không thành công.", - "saveSuccess": "Đã lưu thành công Webhook.", - "saveFailed": "Không lưu được webhook.", - "loadFailed": "Không tải được webhook.", + "never": "Không bao giờ", + "failureCount": "{count, plural, =0 {không có lần thất bại} one {# lần thất bại} other {# lần thất bại}}", + "testWebhook": "Gửi thử nghiệm", + "testSuccess": "Đã gửi webhook thử nghiệm thành công.", + "testFailed": "Gửi webhook thử nghiệm thất bại.", + "saveSuccess": "Đã lưu webhook thành công.", + "saveFailed": "Không thể lưu webhook.", + "loadFailed": "Không thể tải webhook.", "delete": "Xóa", "deleteConfirm": "Bạn có chắc chắn muốn xóa webhook này không?", - "deleteSuccess": "Webhook đã được xóa thành công.", - "deleteFailed": "Không xóa được webhook.", + "deleteSuccess": "Đã xóa webhook thành công.", + "deleteFailed": "Không thể xóa webhook.", "edit": "Chỉnh sửa", "enable": "Kích hoạt", "disable": "Vô hiệu hóa", - "noWebhooks": "Chưa có webhooks nào được định cấu hình.", - "signatureTitle": "Chữ ký Webhook", - "signatureDescription": "Mỗi lần phân phối bao gồm tiêu đề X-Webhook-Signature được ký bằng HMAC-SHA256 bằng bí mật webhook. Xác minh chữ ký trước khi tin cậy tải trọng.", + "noWebhooks": "Chưa có webhook nào được cấu hình.", + "signatureTitle": "Chữ ký webhook", + "signatureDescription": "Mỗi lần gửi đều bao gồm header X-Webhook-Signature được ký bằng HMAC-SHA256 bằng khóa bí mật webhook. Hãy xác minh chữ ký trước khi tin cậy dữ liệu.", "wizard": { - "cancel": "__MISSING__:Cancel", - "step1Title": "__MISSING__:Select Integration", - "step2Title": "__MISSING__:Configure Target", - "step3Title": "__MISSING__:Events & Test", - "back": "__MISSING__:Back", - "next": "__MISSING__:Next", - "finish": "__MISSING__:Finish", - "step1Desc": "__MISSING__:Select the target integration system for this webhook." + "cancel": "Hủy", + "step1Title": "Chọn tích hợp", + "step2Title": "Cấu hình mục tiêu", + "step3Title": "Sự kiện & Thử nghiệm", + "back": "Quay lại", + "next": "Tiếp theo", + "finish": "Hoàn tất", + "step1Desc": "Chọn hệ thống tích hợp mục tiêu cho webhook này." }, "howItWorks": { - "step1": "__MISSING__:Choose an integration provider (e.g. Slack, Discord, custom webhook) and set up the connection details.", - "step2": "__MISSING__:Configure system events to subscribe to (e.g. completion errors, model fallbacks, or usage limits).", - "step3": "__MISSING__:Verify the configuration by sending a test payload to make sure the endpoint receives it.", - "step4": "__MISSING__:Secure your endpoint by validating the X-Webhook-Signature HMAC-SHA256 header using the webhook's secret.", - "title": "__MISSING__:How Webhooks Work", - "customOnly": "__MISSING__:Only applicable for custom endpoint integrations.", - "hmacRecipeTitle": "__MISSING__:HMAC Verification Recipe", - "hmacRecipe": "__MISSING__:To verify webhook payloads in Node.js, compute the HMAC-SHA256 of the raw request body using your secret key. Compare it to the X-Webhook-Signature header using timingSafeEqual.", - "timeoutNote": "__MISSING__:Webhook deliveries have a timeout of 10 seconds.", - "retryNote": "__MISSING__:Failed deliveries are retried up to 5 times with exponential backoff.", - "docsLink": "__MISSING__:Read the full Webhooks developer guide", - "hmacRecipePython": "__MISSING__:Python HMAC verification: hmac.new(secret, body, hashlib.sha256).hexdigest()", - "hmacRecipeBash": "__MISSING__:Bash HMAC verification: echo -n \"$body\" | openssl dgst -sha256 -hmac \"$secret\"" + "step1": "Chọn một nhà cung cấp tích hợp (ví dụ: Slack, Discord, webhook tùy chỉnh) và thiết lập chi tiết kết nối.", + "step2": "Cấu hình các sự kiện hệ thống cần đăng ký theo dõi (ví dụ: lỗi khi hoàn tất, dự phòng mô hình hoặc giới hạn mức sử dụng).", + "step3": "Xác minh cấu hình bằng cách gửi dữ liệu thử nghiệm để đảm bảo endpoint nhận được dữ liệu đó.", + "step4": "Bảo mật endpoint của bạn bằng cách xác thực header HMAC-SHA256 X-Webhook-Signature bằng khóa bí mật của webhook.", + "title": "Cách hoạt động của webhook", + "customOnly": "Chỉ áp dụng cho các tích hợp endpoint tùy chỉnh.", + "hmacRecipeTitle": "Hướng dẫn xác minh HMAC", + "hmacRecipe": "Để xác minh dữ liệu webhook trong Node.js, hãy tính HMAC-SHA256 của phần thân thô của yêu cầu bằng khóa bí mật của bạn. So sánh kết quả với header X-Webhook-Signature bằng timingSafeEqual.", + "timeoutNote": "Các lần gửi webhook có thời gian chờ là 10 giây.", + "retryNote": "Các lần gửi thất bại được thử lại tối đa 5 lần với thời gian chờ tăng theo cấp số nhân.", + "docsLink": "Đọc toàn bộ hướng dẫn dành cho nhà phát triển về webhook", + "hmacRecipePython": "Xác minh HMAC bằng Python: hmac.new(secret, body, hashlib.sha256).hexdigest()", + "hmacRecipeBash": "Xác minh HMAC bằng Bash: echo -n \"$body\" | openssl dgst -sha256 -hmac \"$secret\"" }, "deliveries": { - "title": "__MISSING__:Delivery Logs", - "loadFailed": "__MISSING__:Failed to load webhook delivery logs.", - "empty": "__MISSING__:No deliveries recorded yet. Trigger an event or send a test payload.", - "status": "__MISSING__:Status", - "event": "__MISSING__:Event", - "latency": "__MISSING__:Latency", - "at": "__MISSING__:Sent At" + "title": "Nhật ký gửi", + "loadFailed": "Không thể tải nhật ký gửi webhook.", + "empty": "Chưa có lượt gửi nào được ghi nhận. Hãy kích hoạt một sự kiện hoặc gửi một payload thử nghiệm.", + "status": "Trạng thái", + "event": "Sự kiện", + "latency": "Độ trễ", + "at": "Thời điểm gửi" }, "kinds": { - "comingSoon": "__MISSING__:Coming Soon", - "slack": "__MISSING__:Slack", - "slackDesc": "__MISSING__:Post system events directly into a Slack channel", - "telegram": "__MISSING__:Telegram", - "telegramDesc": "__MISSING__:Send event messages using a Telegram bot", - "discord": "__MISSING__:Discord", - "discordDesc": "__MISSING__:Deliver real-time updates directly to a Discord server", - "custom": "__MISSING__:Custom Webhook", - "customDesc": "__MISSING__:Deliver system event payloads to any HTTPS endpoint", - "email": "__MISSING__:Email Notification", - "emailDesc": "__MISSING__:Receive summary updates via email", - "pagerduty": "__MISSING__:PagerDuty", - "pagerdutyDesc": "__MISSING__:Trigger alerts on PagerDuty for critical system issues", - "teams": "__MISSING__:Microsoft Teams", - "teamsDesc": "__MISSING__:Forward system notifications to Microsoft Teams channels" + "comingSoon": "Sắp có", + "slack": "Slack", + "slackDesc": "Đăng các sự kiện hệ thống trực tiếp vào một kênh Slack", + "telegram": "Telegram", + "telegramDesc": "Gửi thông báo sự kiện bằng một bot Telegram", + "discord": "Discord", + "discordDesc": "Gửi cập nhật theo thời gian thực trực tiếp đến một máy chủ Discord", + "custom": "Webhook tùy chỉnh", + "customDesc": "Gửi dữ liệu sự kiện hệ thống đến bất kỳ endpoint HTTPS nào", + "email": "Thông báo qua email", + "emailDesc": "Nhận cập nhật tổng hợp qua email", + "pagerduty": "PagerDuty", + "pagerdutyDesc": "Kích hoạt cảnh báo trên PagerDuty cho các sự cố hệ thống nghiêm trọng", + "teams": "Microsoft Teams", + "teamsDesc": "Chuyển tiếp thông báo hệ thống đến các kênh Microsoft Teams" }, - "testPayloadSent": "__MISSING__:Test Payload Sent", - "testResponse": "__MISSING__:Test Response", + "testPayloadSent": "Đã gửi dữ liệu thử nghiệm", + "testResponse": "Phản hồi thử nghiệm", "validateUrl": { - "checking": "__MISSING__:Checking URL...", - "ok": "__MISSING__:URL is valid", - "blockedPrivate": "__MISSING__:URL is a blocked private address", - "invalidUrl": "__MISSING__:Invalid URL format" + "checking": "Đang kiểm tra URL...", + "ok": "URL hợp lệ", + "blockedPrivate": "URL là một địa chỉ riêng bị chặn", + "invalidUrl": "Định dạng URL không hợp lệ" }, "custom": { - "endpointUrl": "__MISSING__:Endpoint URL", - "endpointUrlPlaceholder": "__MISSING__:https://api.yourdomain.com/webhook", - "secretKey": "__MISSING__:Secret Key", - "secretKeyPlaceholder": "__MISSING__:Enter secret key or leave blank to auto-generate", - "secretKeyHint": "__MISSING__:Used to sign the payload header for authentication." + "endpointUrl": "URL của endpoint", + "endpointUrlPlaceholder": "https://api.yourdomain.com/webhook", + "secretKey": "Khóa bí mật", + "secretKeyPlaceholder": "Nhập khóa bí mật hoặc để trống để tự động tạo", + "secretKeyHint": "Được dùng để ký header dữ liệu nhằm xác thực." }, "discord": { - "webhookUrl": "__MISSING__:Discord Webhook URL", - "webhookUrlPlaceholder": "__MISSING__:https://discord.com/api/webhooks/...", - "webhookUrlHint": "__MISSING__:The webhook URL copied from your Discord channel integration settings.", - "tutorial": "__MISSING__:How to create a Discord webhook:" + "webhookUrl": "URL webhook Discord", + "webhookUrlPlaceholder": "https://discord.com/api/webhooks/...", + "webhookUrlHint": "URL webhook được sao chép từ cài đặt tích hợp kênh Discord của bạn.", + "tutorial": "Cách tạo webhook Discord:" }, "slack": { - "webhookUrl": "__MISSING__:Slack Webhook URL", - "webhookUrlPlaceholder": "__MISSING__:https://hooks.slack.com/services/...", - "webhookUrlHint": "__MISSING__:The webhook URL copied from your Slack Incoming Webhooks integration.", - "tutorial": "__MISSING__:How to create a Slack webhook:" + "webhookUrl": "URL webhook Slack", + "webhookUrlPlaceholder": "https://hooks.slack.com/services/...", + "webhookUrlHint": "URL webhook được sao chép từ tích hợp Incoming Webhooks của Slack.", + "tutorial": "Cách tạo webhook Slack:" }, "telegram": { - "botToken": "__MISSING__:Telegram Bot Token", - "botTokenPlaceholder": "__MISSING__:123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ", - "botTokenHint": "__MISSING__:The HTTP API token received from @BotFather when creating your bot.", - "chatId": "__MISSING__:Telegram Chat ID / Channel", - "chatIdPlaceholder": "__MISSING__:-100123456789 or @channelname", - "chatIdHint": "__MISSING__:The unique numerical identifier or public username of the chat/channel.", - "tutorial": "__MISSING__:How to configure Telegram webhook:" + "botToken": "Token của bot Telegram", + "botTokenPlaceholder": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ", + "botTokenHint": "Token HTTP API nhận được từ @BotFather khi tạo bot của bạn.", + "chatId": "ID cuộc trò chuyện / kênh Telegram", + "chatIdPlaceholder": "-100123456789 hoặc @channelname", + "chatIdHint": "Mã định danh số duy nhất hoặc tên người dùng công khai của cuộc trò chuyện/kênh.", + "tutorial": "Cách cấu hình webhook Telegram:" } }, "compliance": { "auditTitle": "Kiểm toán", - "auditDescription": "Xem xét các sự kiện tuân thủ và lệnh gọi công cụ MCP từ một chế độ xem hoạt động.", + "auditDescription": "Xem xét các sự kiện tuân thủ và lệnh gọi công cụ MCP trong một chế độ xem vận hành duy nhất.", "complianceTab": "Tuân thủ", "mcpTab": "Kiểm toán MCP", - "title": "Kiểm tra tuân thủ", - "description": "Các sự kiện chính sách, quyền truy cập, nhà cung cấp và bảo mật được ghi lại trong nhật ký kiểm tra tuân thủ.", + "title": "Kiểm toán tuân thủ", + "description": "Các sự kiện chính sách, quyền truy cập, nhà cung cấp và bảo mật được ghi lại trong nhật ký kiểm toán tuân thủ.", "eventType": "Loại sự kiện", "eventTypePlaceholder": "Lọc theo hành động hoặc loại sự kiện", "severity": "Mức độ nghiêm trọng", "allSeverities": "Tất cả các mức độ nghiêm trọng", "info": "Thông tin", "warning": "Cảnh báo", - "critical": "Quan trọng", + "critical": "Nghiêm trọng", "sourceIp": "IP nguồn", "userOrKey": "Người dùng/Khóa", - "action": "hành động", - "result": "kết quả", + "action": "Hành động", + "result": "Kết quả", "details": "Chi tiết", "timestamp": "Dấu thời gian", "from": "Từ", "to": "Đến", "refresh": "Làm mới", - "export": "Xuất khẩu", + "export": "Xuất", "clearFilters": "Xóa bộ lọc", - "loading": "Đang tải sự kiện kiểm tra...", - "showing": "Đang hiển thị {count} trong số {total} sự kiện", + "loading": "Đang tải sự kiện kiểm toán...", + "showing": "Đang hiển thị {count}/{total} sự kiện", "policyViolation": "Vi phạm chính sách", "accessDenied": "Truy cập bị từ chối", - "injectionBlocked": "Tiêm bị chặn", + "injectionBlocked": "Đã chặn Injection", "noEvents": "Không có sự kiện tuân thủ nào được ghi lại.", - "failedFetch": "Không tìm nạp được nhật ký kiểm tra tuân thủ.", + "failedFetch": "Không thể tải nhật ký kiểm toán tuân thủ.", "viewDetails": "Xem chi tiết", - "closeDetails": "Đóng chi tiết", + "closeDetails": "Đóng thông tin chi tiết", "notAvailable": "—", "system": "hệ thống", - "previous": "trước đó", + "previous": "Trước đó", "next": "Tiếp theo", "mcpAudit": "Kiểm toán MCP", - "mcpAuditDesc": "Các mục kiểm tra cuộc gọi công cụ được ghi lại bởi máy chủ MCP.", - "failedFetchMcpAudit": "Không tìm nạp được nhật ký kiểm tra MCP.", + "mcpAuditDesc": "Các mục kiểm toán lệnh gọi công cụ được máy chủ MCP ghi lại.", + "failedFetchMcpAudit": "Không thể tải nhật ký kiểm toán MCP.", "tool": "Công cụ", "toolPlaceholder": "Lọc theo tên công cụ", "duration": "Thời lượng", "apiKey": "Khóa API", - "output": "đầu ra", + "output": "Đầu ra", "allResults": "Tất cả kết quả", - "success": "thành công", + "success": "Thành công", "failure": "Thất bại", - "noMcpEvents": "Không có sự kiện kiểm tra MCP nào được ghi lại.", + "noMcpEvents": "Không có sự kiện kiểm toán MCP nào được ghi lại.", "a2aAudit": "Kiểm toán A2A", - "a2aAuditDesc": "Dấu vết kiểm tra thực hiện nhiệm vụ được ghi lại bởi máy chủ A2A.", - "a2aShowingTasks": "Đang hiển thị {count} trong số {total} nhiệm vụ", - "a2aSkill": "kỹ năng", + "a2aAuditDesc": "Dấu vết kiểm toán thực thi nhiệm vụ được máy chủ A2A ghi lại.", + "a2aShowingTasks": "Đang hiển thị {count}/{total} nhiệm vụ", + "a2aSkill": "Kỹ năng", "a2aSkillPlaceholder": "Lọc theo tên kỹ năng", - "a2aState": "tiểu bang", - "a2aAllStates": "Tất cả các tiểu bang", + "a2aState": "Trạng thái", + "a2aAllStates": "Tất cả trạng thái", "a2aStateSubmitted": "Đã gửi", - "a2aStateWorking": "Đang làm việc", + "a2aStateWorking": "Đang thực hiện", "a2aStateCompleted": "Đã hoàn thành", - "a2aStateFailed": "thất bại", + "a2aStateFailed": "Thất bại", "a2aStateCancelled": "Đã hủy", "a2aTaskId": "ID nhiệm vụ", "a2aEvents": "Sự kiện", - "a2aArtifacts": "Hiện vật", - "a2aNoTasks": "Không có tác vụ A2A nào được ghi lại.", - "a2aLoadingTasks": "Đang tải nhiệm vụ A2A..." + "a2aArtifacts": "Tạo tác", + "a2aNoTasks": "Không có nhiệm vụ A2A nào được ghi lại.", + "a2aLoadingTasks": "Đang tải nhiệm vụ A2A...", + "actor": "Actor", + "actorPlaceholder": "Filter by actor", + "eventTypes": { + "apiKey": { + "activate": "API Key Activated", + "ban": "API Key Banned", + "deactivate": "API Key Deactivated", + "regenerate": "API Key Regenerated", + "scopes": { + "grant": "API Key Scopes Granted", + "revoke": "API Key Scopes Revoked", + "update": "API Key Scopes Updated" + }, + "unban": "API Key Unbanned" + }, + "auth": { + "login": { + "error": "Login Error", + "failed": "Login Failed", + "locked": "Login Locked", + "misconfigured": "Login Misconfigured", + "setup_required": "Login Setup Required", + "success": "Login Success" + }, + "logout": { + "success": "Logout Success" + } + }, + "compliance": { + "cleanup": "Compliance Cleanup" + }, + "provider": { + "credentials": { + "applied": "Provider Credentials Applied", + "batch_revoked": "Provider Credentials Batch Revoked", + "bulk_created": "Provider Credentials Bulk Created", + "bulk_imported": "Provider Credentials Bulk Imported", + "created": "Provider Credentials Created", + "imported": "Provider Credentials Imported", + "revoked": "Provider Credentials Revoked", + "updated": "Provider Credentials Updated" + }, + "validation": { + "ssrf_blocked": "Provider SSRF Blocked" + } + }, + "quota": { + "plan": { + "updated": "Quota Plan Updated" + }, + "pool": { + "created": "Quota Pool Created", + "deleted": "Quota Pool Deleted", + "updated": "Quota Pool Updated" + }, + "store": { + "driver_changed": "Quota Store Driver Changed" + } + }, + "server": { + "start": "Server Start" + }, + "service": { + "reveal_api_key": "Service API Key Revealed" + }, + "settings": { + "update": "Settings Updated", + "update_failed": "Settings Update Failed" + }, + "sync": { + "token": { + "created": "Sync Token Created", + "revoked": "Sync Token Revoked" + } + } + } }, "themesPage": { - "title": "Themes", - "description": "Choose a preset theme or create your own with a single color", - "presetColors": "Popular colors", - "customTheme": "Custom theme", - "customThemeDesc": "Click create theme and pick one color", - "createTheme": "Create theme", - "activePreset": "Active theme" + "title": "Chủ đề", + "description": "Chọn một chủ đề có sẵn hoặc tự tạo chủ đề của riêng bạn với một màu duy nhất", + "presetColors": "Các màu phổ biến", + "customTheme": "Chủ đề tùy chỉnh", + "customThemeDesc": "Nhấp vào \"Tạo chủ đề\" và chọn một màu", + "createTheme": "Tạo chủ đề", + "activePreset": "Chủ đề đang hoạt động" }, "header": { "logout": "Đăng xuất", "language": "Ngôn ngữ", "providers": "Nhà cung cấp", "providerDescription": "Quản lý kết nối nhà cung cấp AI của bạn", - "combos": "Combo", - "comboDescription": "Kết hợp mô hình với dự phòng", - "usage": "Cách sử dụng & phân tích", - "usageDescription": "Giám sát việc sử dụng API, mức tiêu thụ mã thông báo và nhật ký yêu cầu của bạn", + "combos": "Tổ hợp", + "comboDescription": "Các tổ hợp mô hình có tính năng dự phòng", + "usage": "Mức sử dụng & Phân tích", + "usageDescription": "Giám sát mức sử dụng API, mức tiêu thụ token và nhật ký yêu cầu của bạn", "analytics": "Phân tích", "analyticsDescription": "Biểu đồ, xu hướng và thông tin đánh giá", "cliTools": "Công cụ CLI", "cliToolsDescription": "Định cấu hình công cụ CLI", "home": "Trang chủ", "homeDescription": "Chào mừng đến với OmniRoute", - "endpoint": "Endpoints", - "endpointDescription": "Manage proxy endpoints, MCP, A2A, and API endpoints", - "mcp": "MCP", - "mcpDescription": "Model Context Protocol server management and tools", - "a2a": "A2A", - "a2aDescription": "Agent-to-Agent protocol tasks and observability", + "endpoint": "Endpoint", + "endpointDescription": "Quản lý các endpoint proxy, MCP, A2A và API", + "mcp": "Máy chủ MCP", + "mcpDescription": "Quản lý máy chủ Model Context Protocol và các công cụ", + "a2a": "Máy chủ A2A", + "a2aDescription": "Nhiệm vụ giao thức Agent-to-Agent và khả năng giám sát", "settings": "Cài đặt", "settingsDescription": "Quản lý tùy chọn của bạn", "openaiCompatible": "Tương thích OpenAI", - "anthropicCompatible": "Tương thích với con người", - "media": "Media", - "mediaDescription": "Generate images, videos, and music", - "themes": "Themes", - "themesDescription": "Choose a color theme for the whole dashboard panel", - "costsDescription": "Track spending, analyze trends, and manage your AI budget across all providers", - "cacheDescription": "Monitor provider prompt cache efficiency and local semantic response reuse.", - "limitsDescription": "Configure rate limits and quotas per API key and provider", - "runtimeDescription": "Live runtime observability — circuit breakers, cooldowns, model lockouts, sessions and quota alerts", - "apiManagerDescription": "Manage API keys and access control for your OmniRoute instance", - "batchDescription": "Process large volumes of requests asynchronously with batched API calls", - "contextCavemanDescription": "Rule-based message compression, language packs, analytics and output mode controls.", - "contextRtkDescription": "Command-aware compression for tool output, terminal logs and build results.", - "contextCombosDescription": "Define how engines are combined for different routing scenarios.", - "changelogDescription": "Stay up to date with the latest platform features and announcements.", - "agentsDescription": "Manage and configure AI agent tools: Codex, Devin, Jules, and custom agents", - "cloudAgentsDescription": "Orchestrate cloud-based AI agents with live task tracking and plan approval", - "memoryDescription": "Persistent conversational memory with semantic search and FTS5 full-text indexing", - "skillsDescription": "Install and manage sandbox skills for automated prompt and tool execution", - "agentSkillsDescription": "Agent-ready skills catalog with one-click URL copy for AI client integration", - "translatorDescription": "Translate and test prompts across API formats: OpenAI ↔ Claude ↔ Gemini", - "playgroundDescription": "Test prompts interactively with live provider responses and format inspection", - "searchToolsDescription": "Search analytics, provider breakdown, cache hit rates, and cost tracking", - "logsDescription": "Real-time request logs, error traces, and streaming event inspector", - "auditDescription": "Compliance audit trail of API key usage, MCP tool calls, and policy events", - "webhooksDescription": "Configure webhook endpoints to receive real-time event notifications", - "healthDescription": "System health overview: providers, circuit breakers, rate limits, and database", - "proxyDescription": "Configure upstream proxy settings for outbound provider connections", - "apiEndpointsDescription": "Manage custom API endpoint configurations and routing overrides", - "batchFilesDescription": "Browse and manage batch job output files and results", - "analyticsEvalsDescription": "Model evaluation results and performance benchmarks", - "analyticsSearchDescription": "Search query analytics, cache hit rates, and cost tracking", - "analyticsUtilizationDescription": "Provider utilization metrics and capacity planning", - "analyticsComboHealthDescription": "Real-time health and performance of combo routing configurations", - "analyticsCompressionDescription": "Context compression analytics and token savings", - "costsBudgetDescription": "Budget limits and spending alerts per API key and provider", - "costsPricingDescription": "Custom pricing configuration for token cost calculations", - "logsProxyDescription": "Upstream proxy request logs and traffic inspection", - "logsConsoleDescription": "Application console output and debug logs", - "logsActivityDescription": "Audit trail of user actions and system events", - "auditMcpDescription": "MCP tool invocation audit trail and compliance records", + "anthropicCompatible": "Tương thích Anthropic", + "media": "Đa phương tiện", + "mediaDescription": "Tạo hình ảnh, video và âm nhạc", + "themes": "Chủ đề", + "themesDescription": "Chọn chủ đề màu sắc cho toàn bộ bảng điều khiển", + "costsDescription": "Theo dõi chi tiêu, phân tích xu hướng và quản lý ngân sách AI của bạn trên tất cả các nhà cung cấp", + "cacheDescription": "Theo dõi hiệu quả cache prompt của nhà cung cấp và tái sử dụng phản hồi ngữ nghĩa cục bộ.", + "limitsDescription": "Cấu hình giới hạn tốc độ và hạn mức cho mỗi khóa API và nhà cung cấp", + "runtimeDescription": "Khả năng quan sát thời gian chạy trực tiếp — bộ ngắt mạch, thời gian chờ, khóa mô hình, phiên và cảnh báo hạn mức", + "apiManagerDescription": "Quản lý khóa API và kiểm soát truy cập cho bản cài đặt OmniRoute của bạn", + "batchDescription": "Xử lý khối lượng lớn các yêu cầu một cách không đồng bộ bằng các lệnh gọi API theo lô", + "contextCavemanDescription": "Nén tin nhắn dựa trên quy tắc, gói ngôn ngữ, phân tích và kiểm soát chế độ đầu ra.", + "contextRtkDescription": "Nén dựa trên lệnh cho đầu ra công cụ, nhật ký đầu cuối và kết quả bản dựng.", + "contextCombosDescription": "Xác định cách các bộ máy được kết hợp cho các tình huống định tuyến khác nhau.", + "changelogDescription": "Luôn cập nhật các tính năng và thông báo mới nhất của nền tảng.", + "agentsDescription": "Quản lý và cấu hình các công cụ tác nhân AI: Codex, Devin, Jules và các tác nhân tùy chỉnh", + "cloudAgentsDescription": "Điều phối các tác nhân AI trên đám mây với tính năng theo dõi tác vụ trực tiếp và phê duyệt kế hoạch", + "memoryDescription": "Bộ nhớ hội thoại lâu dài với tìm kiếm ngữ nghĩa và lập chỉ mục toàn văn bản FTS5", + "skillsDescription": "Cài đặt và quản lý các kỹ năng trong môi trường sandbox để tự động hóa việc thực thi prompt và công cụ", + "agentSkillsDescription": "Danh mục kỹ năng sẵn sàng cho tác nhân với tính năng sao chép URL chỉ bằng một cú nhấp để tích hợp ứng dụng khách AI", + "translatorDescription": "Dịch và thử nghiệm các prompt trên các định dạng API: OpenAI ↔ Claude ↔ Gemini", + "playgroundDescription": "Kiểm tra prompt một cách tương tác với phản hồi trực tiếp từ nhà cung cấp và kiểm tra định dạng", + "searchToolsDescription": "Phân tích tìm kiếm, phân tích theo nhà cung cấp, tỷ lệ truy cập cache thành công và theo dõi chi phí", + "logsDescription": "Nhật ký yêu cầu theo thời gian thực, dấu vết lỗi và trình kiểm tra sự kiện truyền phát", + "auditDescription": "Dấu vết kiểm toán tuân thủ về mức sử dụng khóa API, các lệnh gọi công cụ MCP và các sự kiện chính sách", + "webhooksDescription": "Cấu hình các endpoint webhook để nhận thông báo sự kiện theo thời gian thực", + "healthDescription": "Tổng quan về tình trạng hệ thống: nhà cung cấp, bộ ngắt mạch, giới hạn tốc độ và cơ sở dữ liệu", + "proxyDescription": "Cấu hình cài đặt proxy thượng nguồn cho các kết nối gửi đi đến nhà cung cấp", + "apiEndpointsDescription": "Quản lý cấu hình endpoint API tùy chỉnh và các ghi đè định tuyến", + "batchFilesDescription": "Duyệt và quản lý các tệp đầu ra cũng như kết quả của tác vụ theo lô", + "analyticsEvalsDescription": "Kết quả đánh giá mô hình và điểm chuẩn hiệu suất", + "analyticsSearchDescription": "Phân tích truy vấn tìm kiếm, tỷ lệ truy cập cache thành công và theo dõi chi phí", + "analyticsUtilizationDescription": "Các chỉ số về mức sử dụng nhà cung cấp và lập kế hoạch công suất", + "analyticsComboHealthDescription": "Tình trạng và hiệu suất theo thời gian thực của các cấu hình định tuyến kết hợp", + "analyticsCompressionDescription": "Phân tích nén ngữ cảnh và mức tiết kiệm token", + "costsBudgetDescription": "Giới hạn ngân sách và cảnh báo chi tiêu cho mỗi khóa API và nhà cung cấp", + "costsPricingDescription": "Cấu hình định giá tùy chỉnh để tính toán chi phí token", + "logsProxyDescription": "Nhật ký yêu cầu của proxy thượng nguồn và kiểm tra lưu lượng", + "logsConsoleDescription": "Đầu ra bảng điều khiển của ứng dụng và nhật ký gỡ lỗi", + "logsActivityDescription": "Dấu vết kiểm toán của các hành động người dùng và sự kiện hệ thống", + "auditMcpDescription": "Dấu vết kiểm toán việc gọi công cụ MCP và hồ sơ tuân thủ", "auditA2a": "Kiểm toán A2A", - "auditA2aDescription": "Quá trình kiểm tra thực hiện nhiệm vụ A2A, chuyển đổi trạng thái và bản ghi yêu cầu kỹ năng", - "settingsGeneralDescription": "Storage, database, and general instance configuration", - "settingsAppearanceDescription": "Theme, branding, and visual customization", - "settingsAiDescription": "AI behaviors, thinking budgets, vision, and memory settings", - "settingsSecurityDescription": "Authentication, authorization, and access control settings", + "auditA2aDescription": "Dấu vết kiểm toán thực thi tác vụ A2A, các chuyển đổi trạng thái và hồ sơ gọi kỹ năng", + "settingsGeneralDescription": "Cài đặt lưu trữ, cơ sở dữ liệu, sao lưu và thời gian lưu giữ", + "settingsAppearanceDescription": "Chủ đề, thương hiệu và tùy chỉnh giao diện", + "settingsAiDescription": "Cài đặt về hành vi AI, ngân sách suy luận, khả năng thị giác và bộ nhớ", + "settingsSecurityDescription": "Cài đặt xác thực, phân quyền và kiểm soát truy cập", "featureFlags": "Cờ tính năng", "featureFlagsDescription": "Kiểm soát khả năng của hệ thống và các tính năng thử nghiệm", "featureFlagsActive": "{count} đang hoạt động", "featureFlagsInactive": "{count} không hoạt động", - "featureFlagsOverrides": "{count} Ghi đè DB", + "featureFlagsOverrides": "{count} ghi đè DB", "featureFlagsSearch": "Tìm kiếm cờ...", "featureFlagsCategoryAll": "Tất cả", "featureFlagsCategorySecurity": "Bảo mật", @@ -1368,197 +1489,198 @@ "featureFlagsCategoryPolicies": "Chính sách", "featureFlagsCategoryRuntime": "Thời gian chạy", "featureFlagsCategoryCli": "CLI", - "featureFlagsCategoryHealth": "sức khỏe", - "featureFlagsSourceDb": "cơ sở dữ liệu", + "featureFlagsCategoryHealth": "Sức khỏe", + "featureFlagsSourceDb": "DB", "featureFlagsSourceEnv": "ENV", "featureFlagsSourceDefault": "DEF", "featureFlagsReset": "Đặt lại", - "featureFlagsResetAll": "Đặt lại tất cả ghi đè", - "featureFlagsResetAllConfirm": "Bạn có chắc chắn muốn đặt lại tất cả các ghi đè cờ tính năng không? Điều này sẽ hoàn nguyên tất cả các cờ về ENV hoặc giá trị mặc định của chúng.", + "featureFlagsResetAll": "Đặt lại tất cả các ghi đè", + "featureFlagsResetAllConfirm": "Bạn có chắc chắn muốn đặt lại tất cả các ghi đè cờ tính năng không? Điều này sẽ khôi phục tất cả các cờ về giá trị ENV hoặc mặc định của chúng.", "featureFlagsRestartRequired": "Cần khởi động lại để áp dụng", "featureFlagsNoResults": "Không có cờ nào phù hợp với tìm kiếm của bạn", "featureFlagsSaved": "Đã cập nhật cờ", - "featureFlagsError": "Không thể cập nhật cờ", - "settingsRoutingDescription": "Routing rules, model aliases, combo defaults, and degradation settings", - "settingsResilienceDescription": "Circuit breaker, retry, and fallback configuration", - "settingsAdvancedDescription": "Advanced payload rules, request limits, and proxy API settings", - "mitmProxyDescription": "Configure MITM proxy settings for traffic inspection and debugging", - "oneProxyDescription": "Configure 1Proxy settings for advanced proxy chaining" + "featureFlagsError": "Cập nhật cờ thất bại", + "settingsRoutingDescription": "Các quy tắc định tuyến, bí danh mô hình, mặc định kết hợp và cài đặt giảm cấp", + "settingsResilienceDescription": "Cấu hình ngắt mạch, thử lại và dự phòng", + "settingsAdvancedDescription": "Các quy tắc payload nâng cao, giới hạn yêu cầu và cài đặt proxy API", + "mitmProxyDescription": "Định cấu hình cài đặt proxy MITM để kiểm tra và gỡ lỗi lưu lượng truy cập", + "oneProxyDescription": "Định cấu hình cài đặt 1Proxy cho chuỗi proxy nâng cao", + "omniSkillsDescription": "Install and manage sandbox skills for automated prompt and tool execution" }, "home": { "quickStart": "Bắt đầu nhanh", - "quickStartDesc": "Hãy đứng dậy và chạy trong 4 bước. Kết nối nhà cung cấp, mô hình định tuyến, giám sát mọi thứ.", + "quickStartDesc": "Bắt đầu sử dụng chỉ trong 4 bước. Kết nối nhà cung cấp, định tuyến mô hình, giám sát mọi thứ.", "fullDocs": "Tài liệu đầy đủ", "step1Title": "1. Tạo khóa API", - "step1Desc": "Đi tới Endpoint -> Khóa đã đăng ký. Tạo một khóa cho mỗi môi trường.", + "step1Desc": "Đi tới Khóa API. Tạo một khóa cho mỗi môi trường.", "step2Title": "2. Kết nối nhà cung cấp", - "step2Desc": "Thêm tài khoản trong Providers. Hỗ trợ OAuth, Khóa API và các cấp miễn phí.", - "step3Title": "3. Chỉ vào khách hàng của bạn", - "step3Desc": "Đặt URL cơ sở thành {url} trong ứng dụng khách IDE hoặc API của bạn.", + "step2Desc": "Thêm tài khoản trong Nhà cung cấp. Hỗ trợ OAuth, khóa API và các gói miễn phí.", + "step3Title": "3. Trỏ ứng dụng khách của bạn", + "step3Desc": "Đặt URL cơ sở thành {url} trong IDE hoặc ứng dụng khách API của bạn.", "step4Title": "4. Giám sát & tối ưu hóa", - "step4Desc": "Theo dõi mã thông báo, chi phí và lỗi trong Nhật ký yêu cầuAnalytics.", + "step4Desc": "Theo dõi token, chi phí và lỗi trong Nhật ký yêu cầuPhân tích.", "providersOverview": "Tổng quan về nhà cung cấp", - "configuredOf": "{configured} được định cấu hình của {total} nhà cung cấp hiện có", - "noModelsAvailable": "Không có mô hình có sẵn cho nhà cung cấp này.", + "configuredOf": "Đã cấu hình {configured} trên tổng số {total} nhà cung cấp có sẵn", + "noModelsAvailable": "Không có mô hình nào khả dụng cho nhà cung cấp này.", "noProvidersConfigured": "Chưa có nhà cung cấp nào được định cấu hình", "addProvider": "Thêm nhà cung cấp", "configureFirst": "Trước tiên hãy định cấu hình kết nối trong {providers}", - "configureProvider": "Định cấu hình nhà cung cấp", - "modelAvailable": "Có mẫu {count}", - "modelsAvailable": "Có sẵn mẫu {count}", + "configureProvider": "Cấu hình nhà cung cấp", + "modelAvailable": "{count} mô hình khả dụng", + "modelsAvailable": "{count} mô hình khả dụng", "connectionsActive": "{count} kết nối đang hoạt động", "connectionsActivePlural": "{count} kết nối đang hoạt động", - "copyModelName": "Sao chép tên mẫu", + "copyModelName": "Sao chép tên mô hình", "documentation": "Tài liệu", - "healthMonitor": "Theo dõi sức khỏe", - "reportIssue": "Báo cáo vấn đề", - "activeError": "{active} đang hoạt động · Lỗi {errors}", + "healthMonitor": "Trình theo dõi tình trạng", + "reportIssue": "Báo cáo sự cố", + "activeError": "{active} đang hoạt động · {errors} lỗi", "oauthLabel": "OAuth", "apiKeyLabel": "Khóa API", "requestsShort": "{count} yêu cầu", - "providerModelsTitle": "{provider} - Người mẫu", + "providerModelsTitle": "{provider} - Các mô hình", "copiedModel": "Đã sao chép: {model}", "aliasLabel": "bí danh", "updateNow": "Cập nhật ngay", "updating": "Đang cập nhật...", - "updateAvailableDesc": "Một phiên bản mới có sẵn. Nhấn vào đây để cập nhật.", + "updateAvailableDesc": "Đã có phiên bản mới. Nhấp để cập nhật.", "updateStarted": "Đã bắt đầu cập nhật...", - "reloadingPageAutomatically": "Đang tải lại trang tự động...", - "providerTopology": "Cấu trúc liên kết của nhà cung cấp" + "reloadingPageAutomatically": "Đang tự động tải lại trang...", + "providerTopology": "Cấu trúc liên kết nhà cung cấp" }, "analytics": { "title": "Phân tích", - "usageAnalyticsTitle": "__MISSING__:Usage Analytics", + "usageAnalyticsTitle": "Phân tích mức sử dụng", "diversityScoreTitle": "Đa dạng nhà cung cấp", - "diversityScoreDesc": "__MISSING__:Provider concentration snapshot for the recent traffic window.", - "diversityShannonEntropy": "__MISSING__:Shannon entropy", - "diversityWindow": "__MISSING__:Window: {count} reqs · Last {mins} mins", - "diversityHealthy": "__MISSING__:Healthy Distribution", - "diversityRiskHigh": "__MISSING__:High Vendor Lock-in Risk", - "diversityRiskModerate": "__MISSING__:Moderate Distribution", - "diversityScoreLabel": "__MISSING__:score", - "diversityHigherExplanation": "__MISSING__:Higher values mean traffic is spread across multiple providers.", - "diversityNoData": "__MISSING__:No recent usage data available.", - "chartRequests": "__MISSING__:Requests", - "chartInput": "__MISSING__:Input", - "chartOutput": "__MISSING__:Output", - "chartTotal": "__MISSING__:Total", - "chartCost": "__MISSING__:Cost", - "chartShare": "__MISSING__:Share", - "chartServiceTier": "__MISSING__:Service Tier", - "chartServiceTierSplit": "__MISSING__:Fast / Standard cost split", - "chartCostPct": "__MISSING__:{pct}% of cost", - "chartUsageDetail": "__MISSING__:Usage Detail", - "chartCacheRead": "__MISSING__:Cache read", - "chartCostByProvider": "__MISSING__:Cost by Provider", - "chartNoCostData": "__MISSING__:No cost data", - "chartModelUsageOverTime": "__MISSING__:Model Usage Over Time", - "chartNoData": "__MISSING__:No data", - "chartWeekly": "__MISSING__:Weekly", - "chartModelBreakdown": "__MISSING__:Model Breakdown", - "chartModel": "__MISSING__:Model", - "chartProvider": "__MISSING__:Provider", - "chartProviderBreakdown": "__MISSING__:Provider Breakdown", - "chartDate": "__MISSING__:Date", - "chartRequestsByProviderDate": "__MISSING__:Requests by Provider & Date", - "filterAllKeys": "__MISSING__:All Keys", - "filterSearchKeys": "__MISSING__:Search keys…", - "filterNoKeysMatch": "__MISSING__:No keys match", - "filterOneKey": "__MISSING__:1 key", - "filterMultipleKeys": "__MISSING__:{count} keys", - "rangeToday": "__MISSING__:Today", - "rangeYesterday": "__MISSING__:Yesterday", - "rangeLast3Days": "__MISSING__:Last 3 days", - "rangeThisWeek": "__MISSING__:This week", - "rangeLast14Days": "__MISSING__:Last 14 days", - "rangeThisMonth": "__MISSING__:This month", - "rangeQuickSelect": "__MISSING__:Quick Select", - "rangeStart": "__MISSING__:Start", - "rangeEnd": "__MISSING__:End", - "rangeCancel": "__MISSING__:Cancel", - "rangeApply": "__MISSING__:Apply", - "rangeErrorInvalid": "__MISSING__:Start must be before end", - "period1D": "__MISSING__:1D", - "period7D": "__MISSING__:7D", - "period30D": "__MISSING__:30D", - "period90D": "__MISSING__:90D", - "periodYTD": "__MISSING__:YTD", - "periodAll": "__MISSING__:All", - "totalTokens": "__MISSING__:Total Tokens", - "inputTokens": "__MISSING__:Input Tokens", - "outputTokens": "__MISSING__:Output Tokens", - "estCost": "__MISSING__:Est. Cost", - "infraTitle": "__MISSING__:Infrastructure", - "infraAccounts": "__MISSING__:Accounts", - "infraProviders": "__MISSING__:Providers", - "infraApiKeys": "__MISSING__:API Keys", - "infraModels": "__MISSING__:Models", - "perfTitle": "__MISSING__:Performance", - "perfAvgTokens": "__MISSING__:Avg Tokens/Req", - "perfCostReq": "__MISSING__:Cost/Req", - "perfIoRatio": "__MISSING__:I/O Ratio", - "perfFastReq": "__MISSING__:Fast Requests", - "highlightsTitle": "__MISSING__:Highlights", - "highlightsTopModel": "__MISSING__:Top Model", - "highlightsTopProvider": "__MISSING__:Top Provider", - "highlightsBusiestDay": "__MISSING__:Busiest Day", - "highlightsDiversity": "__MISSING__:Diversity", - "highlightsFallbackRate": "__MISSING__:Fallback Rate", - "customRange": "__MISSING__:Custom", - "overviewDescription": "Giám sát mô hình sử dụng API, mức tiêu thụ mã thông báo, chi phí và xu hướng hoạt động của bạn trên tất cả các nhà cung cấp và mô hình.", - "evalsDescription": "Chạy bộ đánh giá để kiểm tra và xác thực điểm cuối LLM của bạn. So sánh chất lượng mô hình, phát hiện hồi quy và độ trễ điểm chuẩn.", + "diversityScoreDesc": "Ảnh chụp nhanh sự tập trung của nhà cung cấp trong khung thời gian lưu lượng truy cập gần đây.", + "diversityShannonEntropy": "Entropy Shannon", + "diversityWindow": "Khung thời gian: {count} yêu cầu · {mins} phút qua", + "diversityHealthy": "Phân bổ lành mạnh", + "diversityRiskHigh": "Nguy cơ phụ thuộc nhà cung cấp cao", + "diversityRiskModerate": "Phân bổ vừa phải", + "diversityScoreLabel": "điểm", + "diversityHigherExplanation": "Giá trị cao hơn nghĩa là lưu lượng được phân bổ trên nhiều nhà cung cấp.", + "diversityNoData": "Không có dữ liệu mức sử dụng gần đây.", + "chartRequests": "Yêu cầu", + "chartInput": "Đầu vào", + "chartOutput": "Đầu ra", + "chartTotal": "Tổng", + "chartCost": "Chi phí", + "chartShare": "Tỷ trọng", + "chartServiceTier": "Cấp dịch vụ", + "chartServiceTierSplit": "Phân chia chi phí Nhanh / Tiêu chuẩn", + "chartCostPct": "{pct}% chi phí", + "chartUsageDetail": "Chi tiết mức sử dụng", + "chartCacheRead": "Đọc cache", + "chartCostByProvider": "Chi phí theo nhà cung cấp", + "chartNoCostData": "Không có dữ liệu chi phí", + "chartModelUsageOverTime": "Mức sử dụng mô hình theo thời gian", + "chartNoData": "Không có dữ liệu", + "chartWeekly": "Hàng tuần", + "chartModelBreakdown": "Phân tích chi tiết mô hình", + "chartModel": "Mô hình", + "chartProvider": "Nhà cung cấp", + "chartProviderBreakdown": "Phân tích chi tiết nhà cung cấp", + "chartDate": "Ngày", + "chartRequestsByProviderDate": "Yêu cầu theo nhà cung cấp & ngày", + "filterAllKeys": "Tất cả khóa", + "filterSearchKeys": "Tìm kiếm khóa...", + "filterNoKeysMatch": "Không có khóa nào khớp", + "filterOneKey": "1 khóa", + "filterMultipleKeys": "{count} khóa", + "rangeToday": "Hôm nay", + "rangeYesterday": "Hôm qua", + "rangeLast3Days": "3 ngày qua", + "rangeThisWeek": "Tuần này", + "rangeLast14Days": "14 ngày qua", + "rangeThisMonth": "Tháng này", + "rangeQuickSelect": "Chọn nhanh", + "rangeStart": "Bắt đầu", + "rangeEnd": "Kết thúc", + "rangeCancel": "Hủy", + "rangeApply": "Áp dụng", + "rangeErrorInvalid": "Thời gian bắt đầu phải trước thời gian kết thúc", + "period1D": "1D", + "period7D": "7D", + "period30D": "30D", + "period90D": "90D", + "periodYTD": "YTD", + "periodAll": "Tất cả", + "totalTokens": "Tổng số token", + "inputTokens": "Token đầu vào", + "outputTokens": "Token đầu ra", + "estCost": "Chi phí ước tính", + "infraTitle": "Cơ sở hạ tầng", + "infraAccounts": "Tài khoản", + "infraProviders": "Nhà cung cấp", + "infraApiKeys": "Khóa API", + "infraModels": "Mô hình", + "perfTitle": "Hiệu suất", + "perfAvgTokens": "Token/yêu cầu TB", + "perfCostReq": "Chi phí/yêu cầu", + "perfIoRatio": "Tỷ lệ I/O", + "perfFastReq": "Yêu cầu nhanh", + "highlightsTitle": "Điểm nổi bật", + "highlightsTopModel": "Mô hình hàng đầu", + "highlightsTopProvider": "Nhà cung cấp hàng đầu", + "highlightsBusiestDay": "Ngày bận rộn nhất", + "highlightsDiversity": "Tính đa dạng", + "highlightsFallbackRate": "Tỷ lệ dự phòng", + "customRange": "Tùy chỉnh", + "overviewDescription": "Giám sát các mẫu hình sử dụng API, mức tiêu thụ token, chi phí và xu hướng hoạt động trên tất cả nhà cung cấp và mô hình.", + "evalsDescription": "Chạy các bộ đánh giá để kiểm tra và xác thực các endpoint LLM của bạn. So sánh chất lượng mô hình, phát hiện lỗi hồi quy và đo chuẩn độ trễ.", "overview": "Tổng quan", "evals": "Đánh giá", "utilization": "Tỷ lệ sử dụng", - "utilizationDescription": "Xu hướng sử dụng hạn ngạch nhà cung cấp và theo dõi giới hạn tốc độ", - "modelStatus": "Trạng thái mẫu", - "modelStatusCooldown": "Thời gian hồi chiêu", + "utilizationDescription": "Xu hướng sử dụng hạn ngạch và theo dõi giới hạn tốc độ của nhà cung cấp", + "modelStatus": "Trạng thái mô hình", + "modelStatusCooldown": "Thời gian chờ", "modelStatusUnavailable": "Không có sẵn", "modelStatusError": "Lỗi", - "comboHealth": "Sức khỏe Combo", - "comboHealthDescription": "Hạn ngạch cấp combo, phân phối sử dụng và số liệu hiệu suất", - "compressionAnalyticsTitle": "Compression Analytics", - "compressionAnalyticsDescription": "Compression analytics — token savings, mode breakdown, and provider stats.", + "comboHealth": "Tình trạng combo", + "comboHealthDescription": "Hạn ngạch, mức phân bổ sử dụng và chỉ số hiệu suất ở cấp độ combo", + "compressionAnalyticsTitle": "Phân tích nén", + "compressionAnalyticsDescription": "Phân tích nén — số token tiết kiệm được, phân bố theo chế độ và thống kê theo nhà cung cấp.", "autoRoutingTotalAutoRequests": "Tổng số yêu cầu tự động", "autoRoutingAvgSelectionScore": "Điểm lựa chọn trung bình", - "autoRoutingExplorationRate": "Tỷ lệ thăm dò", - "autoRoutingLkgpHitRate": "Tỷ lệ truy cập LKGP", + "autoRoutingExplorationRate": "Tỷ lệ khám phá", + "autoRoutingLkgpHitRate": "Tỷ lệ trúng LKGP", "autoRoutingRequestsByVariant": "Yêu cầu theo biến thể", - "autoRoutingTopRoutedProviders": "Nhà cung cấp định tuyến hàng đầu", - "comboHealthWorstQuotaLeft": "Hạn ngạch tồi tệ nhất còn lại", + "autoRoutingTopRoutedProviders": "Nhà cung cấp được định tuyến nhiều nhất", + "comboHealthWorstQuotaLeft": "Hạn ngạch còn lại thấp nhất", "comboHealthUsageSkew": "Độ lệch sử dụng", "comboHealthSuccessRate": "Tỷ lệ thành công", - "comboHealthQuotaHealth": "Hạn ngạch sức khỏe", + "comboHealthQuotaHealth": "Tình trạng hạn ngạch", "comboHealthRequests": "Yêu cầu", - "comboHealthTokens": "Mã thông báo", + "comboHealthTokens": "Token", "comboHealthAvgLatency": "Độ trễ trung bình", "comboHealthTotalRequests": "Tổng số yêu cầu", - "comboHealthExecutionTargets": "Mục tiêu thực hiện", - "comboHealthSuccess": "thành công", + "comboHealthExecutionTargets": "Mục tiêu thực thi", + "comboHealthSuccess": "Thành công", "comboHealthLatency": "Độ trễ", - "comboHealthQuota": "hạn ngạch", - "comboHealthTitle": "Combo sức khỏe", - "comboHealthUnableToLoad": "Không thể tải sức khỏe kết hợp", + "comboHealthQuota": "Hạn ngạch", + "comboHealthTitle": "Tình trạng combo", + "comboHealthUnableToLoad": "Không thể tải tình trạng combo", "comboHealthGettingStarted": "Bắt đầu", "compressionAnalyticsTotalRequests": "Tổng số yêu cầu", - "compressionAnalyticsTokensSaved": "Mã thông báo đã lưu", - "compressionAnalyticsAvgSavings": "Tiết kiệm trung bình", + "compressionAnalyticsTokensSaved": "Số token tiết kiệm được", + "compressionAnalyticsAvgSavings": "Mức tiết kiệm trung bình", "compressionAnalyticsAvgDuration": "Thời lượng trung bình", - "compressionAnalyticsReceipts": "Biên lai", + "compressionAnalyticsReceipts": "Biên nhận", "compressionAnalyticsFallbacks": "Dự phòng", - "compressionAnalyticsPromptTokens": "Mã thông báo nhắc nhở", - "compressionAnalyticsCompletionTokens": "Mã thông báo hoàn thành", + "compressionAnalyticsPromptTokens": "Token trong prompt", + "compressionAnalyticsCompletionTokens": "Token hoàn thành", "compressionAnalyticsTotalTokens": "Tổng số token", - "compressionAnalyticsCacheTokens": "Mã thông báo bộ đệm", + "compressionAnalyticsCacheTokens": "Token trong cache", "compressionAnalyticsNoDataYet": "Chưa có dữ liệu nén", "searchAnalyticsTotalSearches": "Tổng số tìm kiếm", - "searchAnalyticsCacheHitRate": "Tỷ lệ truy cập bộ đệm", + "searchAnalyticsCacheHitRate": "Tỷ lệ trúng cache", "searchAnalyticsTotalCost": "Tổng chi phí", "searchAnalyticsAvgResponse": "Phản hồi trung bình", "searchAnalyticsNoSearchesYet": "Chưa có tìm kiếm nào", - "providerUtilizationTitle": "Việc sử dụng nhà cung cấp", - "providerUtilizationFailedToLoad": "Không thể tải dữ liệu sử dụng", - "providerUtilizationNoData": "Không có sẵn dữ liệu sử dụng", + "providerUtilizationTitle": "Mức sử dụng nhà cung cấp", + "providerUtilizationFailedToLoad": "Không thể tải dữ liệu mức sử dụng", + "providerUtilizationNoData": "Không có sẵn dữ liệu mức sử dụng", "providerUtilizationGettingStarted": "Bắt đầu", "providerUtilizationLatestSnapshot": "Ảnh chụp nhanh hạn ngạch mới nhất", "providerUtilizationRemainingCapacity": "Công suất còn lại" @@ -1566,87 +1688,87 @@ "apiManager": { "title": "Khóa API", "createKey": "Tạo khóa API", - "key": "Chìa khóa", + "key": "Khóa", "revokeKey": "Thu hồi khóa", "revokeConfirm": "Bạn có chắc chắn muốn thu hồi khóa API này không?", "noKeys": "Chưa có khóa API nào", - "noKeysDesc": "Tạo khóa API đầu tiên để xác thực các yêu cầu tới điểm cuối của bạn", + "noKeysDesc": "Tạo khóa API đầu tiên để xác thực các yêu cầu tới endpoint của bạn", "keyLabel": "Nhãn khóa", "permissions": "Quyền", "expiresAt": "Hết hạn", - "never": "không bao giờ", + "never": "Không bao giờ", "revoke": "Thu hồi", "showKey": "Hiển thị khóa", - "hideKey": "Ẩn phím", + "hideKey": "Ẩn khóa", "copyKey": "Sao chép khóa API", - "allModels": "Tất cả các mô hình", - "selectedModels": "Các mẫu đã chọn", + "allModels": "Tất cả mô hình", + "selectedModels": "Các mô hình đã chọn", "readOnly": "Chỉ đọc", "fullAccess": "Toàn quyền truy cập", "keyManagement": "Quản lý khóa API", - "keyManagementDesc": "Tạo và quản lý khóa API để xác thực các yêu cầu tới điểm cuối của bạn", - "totalKeys": "Tổng số phím", + "keyManagementDesc": "Tạo và quản lý khóa API để xác thực các yêu cầu tới endpoint của bạn", + "totalKeys": "Tổng số khóa", "restricted": "Bị hạn chế", "totalRequests": "Tổng số yêu cầu", - "modelsAvailable": "Các mẫu có sẵn", + "modelsAvailable": "Các mô hình có sẵn", "registeredKeys": "Khóa đã đăng ký", - "keysRegistered": "{count} khóa đã được đăng ký", - "keyRegistered": "Đã đăng ký khóa {count}", - "keysSecurityNote": "Mỗi khóa tách biệt việc theo dõi việc sử dụng và có thể được thu hồi một cách độc lập. Các khóa được che dấu sau khi tạo để bảo mật.", - "createFirstKey": "Tạo chìa khóa đầu tiên của bạn", + "keysRegistered": "{count} khóa đã đăng ký", + "keyRegistered": "{count} khóa đã đăng ký", + "keysSecurityNote": "Mỗi khóa tách biệt việc theo dõi mức sử dụng và có thể được thu hồi độc lập. Các khóa được che giấu sau khi tạo để bảo mật.", + "createFirstKey": "Tạo khóa đầu tiên của bạn", "name": "Tên", - "usage": "Cách sử dụng", + "usage": "Mức sử dụng", "created": "Đã tạo", - "actions": "hành động", + "actions": "Hành động", "reqs": "yêu cầu", "neverUsed": "Chưa bao giờ sử dụng", "deleteConfirm": "Xóa khóa API này?", "usageTips": "Mẹo sử dụng", - "tipAuth": "Sử dụng các khóa API trong tiêu đề Cấp phép làm Người ghi tên YOUR_KEY", - "tipSecure": "Khóa chỉ được hiển thị một lần trong quá trình tạo — hãy lưu trữ chúng một cách an toàn", - "tipSeparate": "Tạo khóa riêng cho các máy khách hoặc môi trường khác nhau", - "tipRestrict": "Hạn chế khóa cho các kiểu máy cụ thể để bảo mật tốt hơn và kiểm soát chi phí", + "tipAuth": "Sử dụng khóa API trong header Authorization dưới dạng Bearer YOUR_KEY", + "tipSecure": "Khóa chỉ được hiển thị một lần trong quá trình tạo — hãy lưu trữ chúng an toàn", + "tipSeparate": "Tạo các khóa riêng biệt cho các ứng dụng khách hoặc môi trường khác nhau", + "tipRestrict": "Hạn chế khóa cho các mô hình cụ thể để bảo mật tốt hơn và kiểm soát chi phí", "keyName": "Tên khóa", - "keyNamePlaceholder": "ví dụ: Khóa sản xuất, Khóa phát triển", - "keyNameDesc": "Chọn tên mô tả để xác định mục đích của khóa này", + "keyNamePlaceholder": "ví dụ: Khóa sản xuất", + "keyNameDesc": "Chọn một tên mô tả để xác định mục đích của khóa này", "managementAccessDesc": "Cho phép khóa API này quản lý cấu hình OmniRoute.", "selfServiceVisibility": "Khả năng hiển thị tự phục vụ", - "selfServiceVisibilityDesc": "Kiểm soát những gì khóa này có thể xem về mức sử dụng của chính nó và hạn mức upstream dùng chung.", - "ownUsageVisibility": "Chi phí và mức dùng token của chính nó", - "ownUsageVisibilityDesc": "Cho phép khóa này gọi endpoint trạng thái của chính nó để xem mức dùng USD, phần trăm ngân sách và tổng token.", + "selfServiceVisibilityDesc": "Kiểm soát những gì khóa này có thể xem về mức sử dụng của chính nó và hạn mức dùng chung của nhà cung cấp phía thượng nguồn.", + "ownUsageVisibility": "Chi phí riêng và mức sử dụng token", + "ownUsageVisibilityDesc": "Cho phép khóa này gọi endpoint trạng thái của chính nó để xem mức sử dụng tính bằng USD, phần trăm ngân sách và tổng số token.", "sharedAccountQuotaVisibility": "Hạn mức tài khoản dùng chung", - "sharedAccountQuotaVisibilityDesc": "Cho phép khóa này xem hạn mức tài khoản upstream dùng chung khi một kết nối rõ ràng được cấu hình.", + "sharedAccountQuotaVisibilityDesc": "Cho phép khóa này xem hạn mức tài khoản dùng chung của nhà cung cấp phía thượng nguồn khi một kết nối cụ thể được cấu hình.", "keyCreated": "Đã tạo khóa API", "keyCreatedSuccess": "Đã tạo khóa thành công!", "keyCreatedNote": "Sao chép và lưu trữ khóa này ngay bây giờ — nó sẽ không được hiển thị lại.", "done": "Xong", "savePermissions": "Lưu quyền", - "endpointRestrictions": "Allowed Endpoints", - "allEndpointsAllowed": "This key can access all API endpoints.", - "endpointsRestricted": "Restricted to {count} endpoint{count, plural, one {} other {s}}.", - "autoResolve": "Auto-Resolve", - "autoResolveDesc": "Auto-resolve ambiguous model names to native provider for this API key.", - "keyActive": "Key Active", - "keyActiveDesc": "Enable or disable this API key. Disabled keys are immediately rejected with 403.", - "accessSchedule": "Access Schedule", - "accessScheduleDesc": "Restrict access to specific hours and days of the week.", - "scheduleFrom": "From", - "scheduleUntil": "Until", - "scheduleDays": "Days", - "scheduleTimezone": "Timezone", - "scheduleTimezoneHint": "Use IANA timezone names, e.g. America/New_York, Europe/Berlin", - "scheduleActive": "Schedule", - "disabled": "Disabled", - "daySun": "Sun", - "dayMon": "Mon", - "dayTue": "Tue", - "dayWed": "Wed", - "dayThu": "Thu", - "dayFri": "Fri", - "daySat": "Sat", + "endpointRestrictions": "Các endpoint được phép", + "allEndpointsAllowed": "Khóa này có thể truy cập tất cả endpoint API.", + "endpointsRestricted": "Bị giới hạn ở {count} endpoint{count, plural, one {} other {s}}.", + "autoResolve": "Tự động phân giải", + "autoResolveDesc": "Tự động phân giải các tên mô hình mơ hồ sang nhà cung cấp gốc cho khóa API này.", + "keyActive": "Khóa đang hoạt động", + "keyActiveDesc": "Bật hoặc tắt khóa API này. Khóa bị vô hiệu hóa sẽ ngay lập tức bị từ chối với lỗi 403.", + "accessSchedule": "Lịch trình truy cập", + "accessScheduleDesc": "Hạn chế truy cập vào các giờ và ngày cụ thể trong tuần.", + "scheduleFrom": "Từ", + "scheduleUntil": "Đến", + "scheduleDays": "Ngày", + "scheduleTimezone": "Múi giờ", + "scheduleTimezoneHint": "Sử dụng tên múi giờ IANA, ví dụ: America/New_York, Europe/Berlin", + "scheduleActive": "Lịch trình", + "disabled": "Đã vô hiệu hóa", + "daySun": "CN", + "dayMon": "Th 2", + "dayTue": "Th 3", + "dayWed": "Th 4", + "dayThu": "Th 5", + "dayFri": "Th 6", + "daySat": "Th 7", "allowAll": "Cho phép tất cả", - "restrict": "hạn chế", - "allowAllInfo": "Chìa khóa này có thể truy cập vào tất cả các mô hình có sẵn.", + "restrict": "Giới hạn", + "allowAllInfo": "Khóa này có thể truy cập tất cả các mô hình hiện có.", "restrictInfo": "Khóa này có thể truy cập {selected} trong số {total} mô hình.", "selected": "{count} đã chọn", "all": "Tất cả", @@ -1654,427 +1776,452 @@ "searchModels": "Tìm kiếm mô hình theo tên hoặc nhà cung cấp...", "noModelsFound": "Không tìm thấy mô hình nào", "keyNameRequired": "Tên khóa là bắt buộc", - "keyNameTooLong": "Tên khóa phải có {max} ký tự trở xuống", + "keyNameTooLong": "Tên khóa phải có tối đa {max} ký tự", "keyNameInvalid": "Tên khóa chỉ có thể chứa chữ cái, số, dấu cách, dấu gạch ngang và dấu gạch dưới", "invalidKeyName": "Tên khóa không hợp lệ", - "failedCreateKey": "Không tạo được khóa", - "failedCreateKeyRetry": "Không tạo được khóa. Vui lòng thử lại.", + "failedCreateKey": "Không thể tạo khóa", + "failedCreateKeyRetry": "Không thể tạo khóa. Vui lòng thử lại.", "invalidKeyId": "ID khóa không hợp lệ", "failedDeleteKey": "Không thể xóa khóa", "failedDeleteKeyRetry": "Không thể xóa khóa. Vui lòng thử lại.", "invalidModelsSelection": "Lựa chọn mô hình không hợp lệ", - "cannotSelectMoreThanModels": "Không thể chọn nhiều hơn {max} mẫu", - "failedUpdatePermissions": "Không cập nhật được quyền", - "failedUpdatePermissionsRetry": "Không cập nhật được quyền. Vui lòng thử lại.", - "unknownProvider": "không rõ", + "cannotSelectMoreThanModels": "Không thể chọn quá {max} mô hình", + "failedUpdatePermissions": "Không thể cập nhật quyền", + "failedUpdatePermissionsRetry": "Không thể cập nhật quyền. Vui lòng thử lại.", + "unknownProvider": "không xác định", "copyMaskedKey": "Sao chép khóa bị che", - "keyOnlyAvailableAtCreation": "Full key available only at creation time — copy it when you first create the key", - "modelsCount": "{count, plural, one {# model} other {# models}}", - "lastUsedOn": "Cuối cùng: {date}", + "keyOnlyAvailableAtCreation": "Khóa đầy đủ chỉ khả dụng tại thời điểm tạo — hãy sao chép khi bạn tạo khóa lần đầu", + "modelsCount": "{count, plural, one {# mô hình} other {# mô hình}}", + "lastUsedOn": "Lần cuối: {date}", "editPermissions": "Chỉnh sửa quyền", - "deleteKey": "Xóa phím", + "deleteKey": "Xóa khóa", "regenerateKey": "Tạo lại khóa", - "regenerateConfirm": "Bạn có chắc chắn muốn tạo lại khóa API này không? Chìa khóa cũ sẽ bị vô hiệu ngay lập tức.", + "regenerateConfirm": "Bạn có chắc chắn muốn tạo lại khóa API này không? Khóa cũ sẽ bị vô hiệu hóa ngay lập tức.", "failedRegenerateKey": "Không thể tạo lại khóa API", "failedRegenerateKeyRetry": "Không thể tạo lại khóa API. Vui lòng thử lại.", "model": "{count} mô hình", "models": "{count} mô hình", "permissionsTitle": "Quyền: {name}", - "allowAllDesc": "Chìa khóa này có thể truy cập vào tất cả các mô hình có sẵn.", + "allowAllDesc": "Khóa này có thể truy cập tất cả các mô hình có sẵn.", "restrictDesc": "Khóa này có thể truy cập {selectedCount} trong số {totalModels} mô hình.", "selectedCount": "{count} đã chọn", "maxActiveSessions": "Số phiên hoạt động tối đa", - "apiManagerCustomRateLimits": "Giới hạn tỷ lệ tùy chỉnh", - "apiManagerCustomRateLimitsDesc": "Ghi đè giới hạn mặc định toàn cầu. Để trống để sử dụng mặc định.", + "apiManagerCustomRateLimits": "Giới hạn tốc độ tùy chỉnh", + "apiManagerCustomRateLimitsDesc": "Ghi đè giới hạn mặc định toàn cục. Để trống để sử dụng mặc định.", "apiManagerRateLimitRequestsPlaceholder": "Yêu cầu", "apiManagerRateLimitReqPer": "yêu cầu /", "apiManagerRateLimitSecondsPlaceholder": "Giây", "apiManagerRemoveLimitTitle": "Xóa giới hạn", - "apiManagerTimezonePlaceholder": "Mỹ/Sao_Paulo", - "noLogPayloadPrivacy": "Quyền riêng tư về tải trọng không cần đăng nhập", + "apiManagerTimezonePlaceholder": "America/Sao_Paulo", + "noLogPayloadPrivacy": "Quyền riêng tư khi không lưu phần thân yêu cầu", "bannedStatus": "Trạng thái bị cấm", "managementApiAccess": "Quyền truy cập API quản lý", "expirationDate": "Ngày hết hạn", "managementAccess": "Quyền truy cập quản lý", "allowedConnections": "Kết nối được phép", - "searchPlaceholder": "__MISSING__:Search by name or token...", - "activeOnly": "__MISSING__:Active only", - "filterStatus": "__MISSING__:STATUS", - "filterType": "__MISSING__:TYPE", - "filterAll": "__MISSING__:All", - "filterStatusActive": "__MISSING__:Active", - "filterStatusDisabled": "__MISSING__:Disabled", - "filterStatusBanned": "__MISSING__:Banned", - "filterStatusExpired": "__MISSING__:Expired", - "filterTypeStandard": "__MISSING__:Standard", - "filterTypeManage": "__MISSING__:Manage", - "filterTypeRestricted": "__MISSING__:Restricted", - "shownOf": "__MISSING__:{shown} of {total} shown", - "emptyFilterTitle": "__MISSING__:No keys match your filters", - "emptyFilterClear": "__MISSING__:Clear filters" + "searchPlaceholder": "Tìm kiếm theo tên hoặc token...", + "activeOnly": "Chỉ đang hoạt động", + "filterStatus": "TRẠNG THÁI", + "filterType": "LOẠI", + "filterAll": "Tất cả", + "filterStatusActive": "Đang hoạt động", + "filterStatusDisabled": "Đã vô hiệu hóa", + "filterStatusBanned": "Bị cấm", + "filterStatusExpired": "Đã hết hạn", + "filterTypeStandard": "Tiêu chuẩn", + "filterTypeManage": "Quản lý", + "filterTypeRestricted": "Hạn chế", + "shownOf": "Đang hiển thị {shown} trong số {total}", + "emptyFilterTitle": "Không có khóa nào khớp với bộ lọc của bạn", + "emptyFilterClear": "Xóa bộ lọc", + "localUsageCommand": "Allow local usage command", + "localUsageCommandDesc": "Allows this API key to use @@om-usage to retrieve cached usage and quota information without calling an upstream provider.", + "localUsageCommandBadge": "Usage cmd", + "streamDefaultMode": "Stream Default Compatibility", + "streamDefaultModeDesc": "Controls omitted `stream` flags for this key. JSON mode returns non-streaming responses unless the client explicitly requests SSE.", + "streamDefaultLegacy": "Legacy", + "streamDefaultJson": "JSON Compatible", + "streamDefaultBadge": "JSON stream default", + "devicesCount": "{count, plural, one {# device} other {# devices}}", + "devicesTooltip": "{count, plural, one {# distinct IP/User-Agent device seen with this key (last 30 min)} other {# distinct IP/User-Agent devices seen with this key (last 30 min)}}", + "viewCostsFor": "View costs for {name}", + "restrictLoading": "Loading model catalog…", + "restrictCatalogUnavailable": "Model catalog unavailable; this key has {selectedCount} selected model restrictions.", + "disableNonPublicModels": "Disable Non-Public Models", + "disableNonPublicModelsDesc": "Reject requests for models that are not discovered or not marked as public in the provider catalog", + "normalKeysSection": "Normal keys", + "quotaKeysSection": "Quota keys", + "quotaPill": "QUOTA", + "quotaModeOnly": "qtSd-only" }, "auditLog": { "title": "Nhật ký kiểm tra", - "searchPlaceholder": "Hành động tìm kiếm...", - "action": "hành động", - "actor": "diễn viên", + "searchPlaceholder": "Tìm kiếm hành động...", + "action": "Hành động", + "actor": "Tác nhân", "target": "Mục tiêu", "ipAddress": "Địa chỉ IP", "timestamp": "Dấu thời gian", - "noEntries": "Không tìm thấy mục kiểm tra nào", + "noEntries": "Không tìm thấy mục nhật ký kiểm tra nào", "filterByAction": "Lọc theo hành động...", - "filterByActor": "Lọc theo diễn viên...", + "filterByActor": "Lọc theo tác nhân...", "filterEntriesAria": "Lọc các mục nhật ký kiểm tra", "filterByActionTypeAria": "Lọc theo loại hành động", - "filterByActorAria": "Lọc theo diễn viên", + "filterByActorAria": "Lọc theo tác nhân", "refreshAuditLogAria": "Làm mới nhật ký kiểm tra", - "tableAria": "Mục nhật ký kiểm tra", - "failedFetchAuditLog": "Không tìm nạp được nhật ký kiểm tra", + "tableAria": "Các mục nhật ký kiểm tra", + "failedFetchAuditLog": "Không thể tải nhật ký kiểm tra", "notAvailable": "—", - "description": "Hành động hành chính và sự kiện bảo mật", - "showing": "Hiển thị các mục {count} (bù đắp {offset})", - "previous": "trước đó" + "description": "Hành động quản trị và sự kiện bảo mật", + "showing": "Đang hiển thị {count} mục (vị trí bắt đầu {offset})", + "previous": "Trước đó" }, "media": { - "title": "Sân chơi phương tiện", + "title": "Khu thử nghiệm phương tiện", "subtitle": "Tạo hình ảnh, video và âm nhạc", - "model": "Model", + "model": "Mô hình", "prompt": "Prompt", "generate": "Tạo", - "generating": "Generating...", - "loadingModels": "Loading available models...", - "noModels": "No models available. Configure providers with media capabilities first.", - "error": "Generation Failed", - "result": "Result", - "imageDescription": "Generate images from text prompts using OpenAI, xAI, Together, Hyperbolic, SD WebUI, ComfyUI and more.", - "videoDescription": "Create videos with AnimateDiff, Stable Video Diffusion via ComfyUI or SD WebUI.", - "musicDescription": "Compose music using Stable Audio Open or MusicGen via ComfyUI.", + "generating": "Đang tạo...", + "loadingModels": "Đang tải các mô hình khả dụng...", + "noModels": "Không có mô hình nào khả dụng. Hãy cấu hình nhà cung cấp có khả năng xử lý phương tiện trước.", + "error": "Tạo thất bại", + "result": "Kết quả", + "imageDescription": "Tạo hình ảnh từ lời nhắc văn bản bằng OpenAI, xAI, Together, Hyperbolic, SD WebUI, ComfyUI và nhiều dịch vụ khác.", + "videoDescription": "Tạo video bằng AnimateDiff, Stable Video Diffusion qua ComfyUI hoặc SD WebUI.", + "musicDescription": "Soạn nhạc sử dụng Stable Audio Open hoặc MusicGen qua ComfyUI.", "kinds": { - "embedding": "__MISSING__:Embedding", - "image": "__MISSING__:Image", - "imageToText": "__MISSING__:Image to Text", - "tts": "__MISSING__:Text to Speech", - "stt": "__MISSING__:Speech to Text", - "webSearch": "__MISSING__:Web Search", - "webFetch": "__MISSING__:Web Fetch", - "video": "__MISSING__:Video", - "music": "__MISSING__:Music" + "embedding": "Embedding", + "image": "Hình ảnh", + "imageToText": "Hình ảnh sang văn bản", + "tts": "Văn bản sang giọng nói", + "stt": "Giọng nói sang văn bản", + "webSearch": "Tìm kiếm web", + "webFetch": "Lấy dữ liệu web", + "video": "Video", + "music": "Âm nhạc", + "ocr": "OCR" }, - "noProviders": "__MISSING__:No providers configured for this kind yet.", - "addConnection": "__MISSING__:Add Connection", - "backToProviders": "__MISSING__:Back to Providers", - "connections": "__MISSING__:{count} Connections", - "noConnections": "__MISSING__:No connections yet — add one from the provider page.", - "loading": "__MISSING__:Loading..." + "noProviders": "Chưa có nhà cung cấp nào được cấu hình cho loại này.", + "addConnection": "Thêm kết nối", + "backToProviders": "Quay lại danh sách nhà cung cấp", + "connections": "{count} kết nối", + "noConnections": "Chưa có kết nối nào — hãy thêm kết nối từ trang nhà cung cấp.", + "loading": "Đang tải...", + "suggestedModels": "Suggested models from provider" }, "search": { - "searchQuery": "Search Query", - "searchResults": "Search Results", - "cachedResult": "Cached", - "searchCost": "Cost", - "searchTools": "Search Tools", - "searchToolsDesc": "Advanced search testing with provider comparison", - "compareProviders": "Compare Providers", - "rerankResults": "Rerank Results", - "searchHistory": "Search History", - "urlOverlap": "URL Overlap", - "noSearchProviders": "No search providers configured. Add providers in Settings.", - "noRerankModels": "No rerank model available", - "webSearch": "Web Search", - "provider": "Provider", - "searchType": "Search Type", - "maxResults": "Max Results", - "filters": "Filters", - "country": "Country", - "language": "Language", - "timeRange": "Time Range", - "includeDomains": "Include Domains", - "excludeDomains": "Exclude Domains", - "safeSearch": "Safe Search", - "safeSearchOff": "Off", - "safeSearchModerate": "Moderate", - "safeSearchStrict": "Strict", - "queryPlaceholder": "Enter search query...", - "providerAuto": "auto (cheapest)", + "searchQuery": "Truy vấn tìm kiếm", + "searchResults": "Kết quả tìm kiếm", + "cachedResult": "Đã cache", + "searchCost": "Chi phí", + "searchTools": "Công cụ tìm kiếm", + "searchToolsDesc": "Thử nghiệm tìm kiếm nâng cao với tính năng so sánh nhà cung cấp", + "compareProviders": "So sánh nhà cung cấp", + "rerankResults": "Xếp hạng lại kết quả", + "searchHistory": "Lịch sử tìm kiếm", + "urlOverlap": "Trùng lặp URL", + "noSearchProviders": "Không có nhà cung cấp tìm kiếm nào được cấu hình. Thêm nhà cung cấp trong phần Cài đặt.", + "noRerankModels": "Không có mô hình xếp hạng lại nào khả dụng", + "webSearch": "Tìm kiếm web", + "provider": "Nhà cung cấp", + "searchType": "Loại tìm kiếm", + "maxResults": "Số kết quả tối đa", + "filters": "Bộ lọc", + "country": "Quốc gia", + "language": "Ngôn ngữ", + "timeRange": "Khoảng thời gian", + "includeDomains": "Bao gồm các miền", + "excludeDomains": "Loại trừ các miền", + "safeSearch": "Tìm kiếm an toàn", + "safeSearchOff": "Tắt", + "safeSearchModerate": "Trung bình", + "safeSearchStrict": "Nghiêm ngặt", + "queryPlaceholder": "Nhập truy vấn tìm kiếm...", + "providerAuto": "tự động (rẻ nhất)", "searchTypeWeb": "web", - "searchTypeNews": "news", - "optionAny": "any", - "timeRangeDay": "Past day", - "timeRangeWeek": "Past week", - "timeRangeMonth": "Past month", - "timeRangeYear": "Past year", + "searchTypeNews": "tin tức", + "optionAny": "bất kỳ", + "timeRangeDay": "Trong ngày qua", + "timeRangeWeek": "Tuần qua", + "timeRangeMonth": "Tháng qua", + "timeRangeYear": "Năm qua", "domainPlaceholder": "example.com", - "requestTimedOut": "Request timed out ({seconds}s)", - "networkError": "Network error", - "formatted": "Formatted", + "requestTimedOut": "Yêu cầu đã hết thời gian chờ ({seconds}s)", + "networkError": "Lỗi mạng", + "formatted": "Đã định dạng", "rawJson": "JSON", "cacheMiss": "cache miss", "cacheHit": "cache hit", - "latency": "Latency", - "cost": "Cost", - "results": "Results", - "rerank": "Rerank", - "rerankModel": "Rerank Model", - "positionDelta": "Position Change", - "emptyState": "Send a search query to see results", + "latency": "Độ trễ", + "cost": "Chi phí", + "results": "Kết quả", + "rerank": "Xếp hạng lại", + "rerankModel": "Mô hình xếp hạng lại", + "positionDelta": "Thay đổi vị trí", + "emptyState": "Gửi truy vấn tìm kiếm để xem kết quả", "copy": "Sao chép", "resetToDefault": "Đặt lại về mặc định", - "tabSearch": "Search", - "tabScrape": "Scrape", - "tabCompare": "Compare", - "modalitiesGuide": "Modalities guide", - "searchConceptTitle": "Search", - "searchConceptDesc": "Search = fetches a list of web results (title, URL, snippet, relevance score)", - "scrapeConceptTitle": "Scrape", - "scrapeConceptDesc": "Scrape = extracts the full content of a URL (markdown, text or HTML)", - "compareConceptTitle": "Compare", - "compareConceptDesc": "Compare = runs the same query across N providers side-by-side to compare latency, cost and result overlap", - "rerankConceptTitle": "Rerank", - "rerankConceptDesc": "Rerank = reorders results via LLM to improve relevance based on the query", - "autoConceptTitle": "Auto (cheapest)", - "autoConceptDesc": "Auto (cheapest) = automatically picks the cheapest available provider with configured credentials", - "providerCatalogTitle": "Provider Catalog", - "kindSearch": "Search", - "kindFetch": "Fetch/Scrape", - "statusConfigured": "Configured", - "statusMissing": "No credential", - "statusRateLimited": "Rate limited", - "configureProvider": "Configure in Providers", - "loadingProviders": "Loading providers…", - "failedToLoadProviders": "Failed to load providers", - "costPerQuery": "Cost/query", - "freeQuota": "Free quota/mo", - "scrapeUrl": "URL to scrape", + "tabSearch": "Tìm kiếm", + "tabScrape": "Trích xuất", + "tabCompare": "So sánh", + "modalitiesGuide": "Hướng dẫn về các chế độ", + "searchConceptTitle": "Tìm kiếm", + "searchConceptDesc": "Tìm kiếm = lấy danh sách các kết quả web (tiêu đề, URL, đoạn trích, điểm mức độ liên quan)", + "scrapeConceptTitle": "Trích xuất", + "scrapeConceptDesc": "Trích xuất = trích xuất toàn bộ nội dung của một URL (Markdown, văn bản hoặc HTML)", + "compareConceptTitle": "So sánh", + "compareConceptDesc": "So sánh = chạy cùng một truy vấn song song trên N nhà cung cấp để so sánh độ trễ, chi phí và mức độ trùng lặp của kết quả", + "rerankConceptTitle": "Xếp hạng lại", + "rerankConceptDesc": "Xếp hạng lại = sắp xếp lại kết quả thông qua LLM để cải thiện mức độ liên quan dựa trên truy vấn", + "autoConceptTitle": "Tự động (rẻ nhất)", + "autoConceptDesc": "Tự động (rẻ nhất) = tự động chọn nhà cung cấp rẻ nhất hiện có với thông tin xác thực đã được định cấu hình", + "providerCatalogTitle": "Danh mục nhà cung cấp", + "kindSearch": "Tìm kiếm", + "kindFetch": "Lấy/Trích xuất", + "statusConfigured": "Đã định cấu hình", + "statusMissing": "Không có thông tin xác thực", + "statusRateLimited": "Bị giới hạn tần suất", + "configureProvider": "Cấu hình trong mục Nhà cung cấp", + "loadingProviders": "Đang tải các nhà cung cấp…", + "failedToLoadProviders": "Không thể tải các nhà cung cấp", + "costPerQuery": "Chi phí/truy vấn", + "freeQuota": "Hạn mức miễn phí/tháng", + "scrapeUrl": "URL cần trích xuất", "scrapeUrlPlaceholder": "https://example.com", - "scrapeExtract": "Extract", - "scrapeExtracting": "Extracting…", - "scrapeFullPage": "Full page", - "scrapeFormat": "Format", + "scrapeExtract": "Trích xuất", + "scrapeExtracting": "Đang trích xuất…", + "scrapeFullPage": "Toàn trang", + "scrapeFormat": "Định dạng", "formatMarkdown": "Markdown", "formatHtml": "HTML", - "formatText": "Text", - "scrapePreview": "Preview", - "scrapeRaw": "Raw", - "scrapeContentTruncated": "(truncated, view raw)", - "scrapeMetadata": "Metadata", - "scrapeProvider": "Provider", - "scrapeSize": "Size", - "compareRun": "Compare", - "compareRunning": "Comparing…", - "autoProvider": "Auto (cheapest)", - "configuredStatus": "Configured", - "rateLimitedStatus": "Rate limited", - "noCredential": "No credential", - "searchTypeLabel": "Type", - "rerankModelLabel": "Rerank model", - "noneOption": "None", - "size": "Size" + "formatText": "Văn bản", + "scrapePreview": "Xem trước", + "scrapeRaw": "Dữ liệu thô", + "scrapeContentTruncated": "(đã cắt bớt, xem dữ liệu thô)", + "scrapeMetadata": "Siêu dữ liệu", + "scrapeProvider": "Nhà cung cấp", + "scrapeSize": "Kích thước", + "compareRun": "So sánh", + "compareRunning": "Đang so sánh…", + "autoProvider": "Tự động (rẻ nhất)", + "configuredStatus": "Đã cấu hình", + "rateLimitedStatus": "Bị giới hạn tốc độ", + "noCredential": "Không có thông tin xác thực", + "searchTypeLabel": "Loại", + "rerankModelLabel": "Mô hình xếp hạng lại", + "noneOption": "Không có", + "size": "Kích thước", + "scrapeUrlRequired": "URL is required", + "scrapeUrlInvalid": "Invalid URL — it must start with http:// or https://", + "scrapeEmptyState": "Enter a URL to extract its content", + "scrapeProvidersAvailable": "Available providers: Firecrawl, Jina Reader, Tavily, TinyFish." }, "cliTools": { "title": "Công cụ CLI", "noActiveProviders": "Không có nhà cung cấp đang hoạt động", - "noActiveProvidersDesc": "Trước tiên, vui lòng thêm và kết nối nhà cung cấp để định cấu hình công cụ CLI.", - "mapModels": "Mô hình bản đồ", + "noActiveProvidersDesc": "Trước tiên, vui lòng thêm và kết nối các nhà cung cấp để định cấu hình các công cụ CLI.", + "mapModels": "Ánh xạ mô hình", "testConnection": "Kiểm tra kết nối", "connectionStatus": "Trạng thái kết nối", - "configureEndpoint": "Định cấu hình điểm cuối", + "configureEndpoint": "Cấu hình endpoint", "instructions": "Hướng dẫn", "modelMapping": "Ánh xạ mô hình", "baseUrl": "URL cơ sở", "apiKey": "Khóa API", - "configured": "Đã định cấu hình", - "notConfigured": "Chưa được định cấu hình", + "configured": "Đã cấu hình", + "notConfigured": "Chưa cấu hình", "notInstalled": "Chưa được cài đặt", - "custom": "tùy chỉnh", + "custom": "Tùy chỉnh", "unknown": "Không xác định", "lastSavedAt": "Đã lưu lần cuối: {date}", - "never": "không bao giờ", - "justNow": "ngay bây giờ", + "never": "Không bao giờ", + "justNow": "vừa xong", "minutesAgoShort": "{count} phút trước", "hoursAgoShort": "{count} giờ trước", - "daysAgoShort": "{count}ngày trước", - "monthsAgoShort": "{count}tháng trước", + "daysAgoShort": "{count} ngày trước", + "monthsAgoShort": "{count} tháng trước", "yearsAgoShort": "{count} năm trước", - "runtimeCheckFailed": "Kiểm tra thời gian chạy không thành công", - "yourApiKeyPlaceholder": "khóa-api-của bạn", - "modelPlaceholder": "nhà cung cấp/id mô hình", + "runtimeCheckFailed": "Không thể kiểm tra môi trường thời gian chạy", + "yourApiKeyPlaceholder": "your-api-key", + "modelPlaceholder": "provider/model-id", "configurationSaved": "Đã lưu cấu hình thành công.", - "failedToSave": "Không lưu được cấu hình.", - "noApiKeysCreateOne": "Không có khóa API - Tạo một khóa trong trang Khóa", + "failedToSave": "Không thể lưu cấu hình.", + "noApiKeysCreateOne": "Không có khóa API - Hãy tạo một khóa trong trang Khóa", "defaultOmnirouteKey": "sk_omniroute (mặc định)", - "selectModel": "Chọn mẫu", - "selectModelForAlias": "Chọn kiểu máy cho {alias}", - "selectModelForTool": "Chọn mẫu cho {tool}", - "select": "chọn", + "selectModel": "Chọn mô hình", + "selectModelForAlias": "Chọn mô hình cho {alias}", + "selectModelForTool": "Chọn mô hình cho {tool}", + "select": "Chọn", "clear": "Xóa", - "comingSoon": "Sắp có", - "checkingRuntime": "Đang kiểm tra trạng thái thời gian chạy...", - "guideOnlyIntegration": "Tích hợp chỉ có hướng dẫn (không yêu cầu thời gian chạy cục bộ)", - "cliRuntimeDetected": "Đã phát hiện và sẵn sàng thời gian chạy CLI", - "cliFoundNotRunnable": "Đã tìm thấy CLI nhưng không thể chạy được{reason}", - "cliRuntimeNotDetected": "Thời gian chạy CLI không được phát hiện", - "binary": "nhị phân", + "comingSoon": "Sắp ra mắt", + "checkingRuntime": "Đang kiểm tra trạng thái môi trường thời gian chạy...", + "guideOnlyIntegration": "Tích hợp chỉ qua hướng dẫn (không yêu cầu môi trường thời gian chạy cục bộ)", + "cliRuntimeDetected": "Đã phát hiện môi trường thời gian chạy CLI và sẵn sàng", + "cliFoundNotRunnable": "Đã tìm thấy CLI nhưng không thể chạy{reason}", + "cliRuntimeNotDetected": "Không phát hiện thấy môi trường thời gian chạy CLI", + "binary": "Tệp nhị phân", "configPath": "Đường dẫn cấu hình", "configPathShort": "Cấu hình", - "failedCheckRuntimeStatus": "Không thể kiểm tra trạng thái thời gian chạy.", + "failedCheckRuntimeStatus": "Không thể kiểm tra trạng thái môi trường thời gian chạy.", "copy": "Sao chép", "copied": "Đã sao chép", "copyConfig": "Sao chép cấu hình", "saveConfig": "Lưu cấu hình", "selectionSaved": "Đã lưu lựa chọn", - "guide": "hướng dẫn", + "guide": "Hướng dẫn", "detected": "Đã phát hiện", "notReady": "Chưa sẵn sàng", "active": "Đang hoạt động", "inactive": "Không hoạt động", "startMitm": "Bắt đầu MITM", "stopMitm": "Dừng MITM", - "mitmStarted": "MITM đã bắt đầu thành công!", - "mitmStopped": "MITM đã dừng thành công!", - "failedStart": "Không khởi động được MITM", + "mitmStarted": "Đã khởi động MITM thành công!", + "mitmStopped": "Đã dừng MITM thành công!", + "failedStart": "Không thể khởi động MITM", "failedStop": "Không thể dừng MITM", - "saveMappings": "Lưu bản đồ", - "mappingsSaved": "Đã lưu bản đồ!", - "failedSaveMappings": "Không lưu được bản đồ", - "howItWorks": "Nó hoạt động như thế nào:", - "antigravityHowWorksDesc": "Phản trọng lực gửi yêu cầu đến điểm cuối của Google. MITM chặn và chuyển hướng chúng đến OmniRoute.", - "antigravityStep1": "1. Khởi động MITM để định tuyến các yêu cầu thông qua OmniRoute.", + "saveMappings": "Lưu ánh xạ", + "mappingsSaved": "Đã lưu ánh xạ!", + "failedSaveMappings": "Không thể lưu ánh xạ", + "howItWorks": "Cách hoạt động:", + "antigravityHowWorksDesc": "Antigravity gửi các yêu cầu đến endpoint của Google. MITM sẽ chặn và chuyển hướng chúng đến OmniRoute.", + "antigravityStep1": "1. Khởi động MITM để định tuyến các yêu cầu qua OmniRoute.", "antigravityStep2Prefix": "2. Thêm", - "antigravityStep2Suffix": "vào tệp máy chủ của bạn dưới dạng 127.0.0.1.", - "antigravityStep3": "3. Mở AntiGravity và các yêu cầu sẽ được ủy quyền.", - "mitmHowWorksDesc": "{toolName} sends requests to its provider endpoint. MITM intercepts and redirects them to OmniRoute.", - "mitmStep1": "1. Start MITM to route requests through OmniRoute.", - "mitmStep2Prefix": "2. Add", - "mitmStep2Suffix": "to your hosts file as 127.0.0.1.", - "mitmStep3": "3. Open {toolName} and requests will be proxied.", - "sudoPasswordRequiredTitle": "Yêu cầu mật khẩu Sudo", - "sudoPasswordHint": "Cần có mật khẩu quản trị viên để sửa đổi cài đặt proxy hệ thống và tệp máy chủ.", + "antigravityStep2Suffix": "vào tệp hosts của bạn với địa chỉ 127.0.0.1.", + "antigravityStep3": "3. Mở Antigravity và các yêu cầu sẽ được chuyển tiếp qua proxy.", + "mitmHowWorksDesc": "{toolName} gửi các yêu cầu đến endpoint của nhà cung cấp. MITM sẽ chặn và chuyển hướng chúng đến OmniRoute.", + "mitmStep1": "1. Khởi động MITM để định tuyến các yêu cầu qua OmniRoute.", + "mitmStep2Prefix": "2. Thêm", + "mitmStep2Suffix": "vào tệp hosts của bạn với địa chỉ 127.0.0.1.", + "mitmStep3": "3. Mở {toolName} và các yêu cầu sẽ được chuyển tiếp qua proxy.", + "sudoPasswordRequiredTitle": "Cần mật khẩu sudo", + "sudoPasswordHint": "Cần có mật khẩu quản trị viên để sửa đổi tệp hosts và cài đặt proxy hệ thống.", "enterSudoPassword": "Nhập mật khẩu sudo", - "sudoPasswordRequiredError": "Mật khẩu Sudo là bắt buộc.", - "cancel": "Hủy bỏ", + "sudoPasswordRequiredError": "Bắt buộc phải nhập mật khẩu sudo.", + "cancel": "Hủy", "confirm": "Xác nhận", - "settingsApplied": "Cài đặt được áp dụng thành công!", + "settingsApplied": "Áp dụng cài đặt thành công!", "failedApplySettings": "Không thể áp dụng cài đặt", - "settingsReset": "Thiết lập lại cài đặt thành công!", + "settingsReset": "Đặt lại cài đặt thành công!", "failedResetSettings": "Không thể đặt lại cài đặt", "backupRestored": "Đã khôi phục bản sao lưu!", "failedRestore": "Không thể khôi phục", "checkingCli": "Đang kiểm tra {tool} CLI...", - "cliNotRunnable": "{tool} CLI đã được cài đặt nhưng không chạy được", + "cliNotRunnable": "{tool} CLI đã được cài đặt nhưng không thể chạy", "cliNotInstalled": "{tool} CLI chưa được cài đặt", - "cliNotDetected": "{tool} CLI không được phát hiện", - "cliDetectedReady": "{tool} CLI đã được phát hiện và sẵn sàng", - "cliFoundFailedHealthcheck": "{tool} CLI đã được tìm thấy nhưng quá trình kiểm tra tình trạng thời gian chạy không thành công{reason}.", + "cliNotDetected": "Không phát hiện thấy {tool} CLI", + "cliDetectedReady": "Đã phát hiện thấy {tool} CLI và sẵn sàng", + "cliFoundFailedHealthcheck": "Tìm thấy {tool} CLI nhưng kiểm tra tình trạng thời gian chạy thất bại{reason}.", "installCliPrompt": "Vui lòng cài đặt {tool} CLI để sử dụng tính năng này.", "installCodexPrompt": "Vui lòng cài đặt Codex CLI để sử dụng tính năng tự động áp dụng.", "hide": "Ẩn", "howToInstall": "Cách cài đặt", "installationGuide": "Hướng dẫn cài đặt", - "platforms": "macOS/Linux/Windows:", + "platforms": "macOS / Linux / Windows:", "afterInstallationRun": "Sau khi cài đặt, hãy chạy", "toVerify": "để xác minh.", - "current": "hiện tại", + "current": "Hiện tại", "baseUrlPlaceholder": "https://.../v1", "resetToDefault": "Đặt lại về mặc định", - "providerModelPlaceholder": "nhà cung cấp/id mô hình", + "providerModelPlaceholder": "nhà cung cấp/id-mô hình", "apply": "Áp dụng", "reset": "Đặt lại", "manualConfig": "Cấu hình thủ công", - "backups": "Sao lưu", - "configBackups": "Cấu hình sao lưu", - "noBackupsYet": "Chưa có bản sao lưu nào. Các bản sao lưu được tạo tự động trước mỗi lần Áp dụng hoặc Đặt lại.", + "backups": "Bản sao lưu", + "configBackups": "Sao lưu cấu hình", + "noBackupsYet": "Chưa có bản sao lưu nào. Các bản sao lưu sẽ được tạo tự động trước mỗi lần áp dụng hoặc đặt lại.", "restore": "Khôi phục", "backupRestoredReloading": "Đã khôi phục bản sao lưu! Đang tải lại trạng thái...", "failedRestoreBackup": "Không thể khôi phục bản sao lưu", "applied": "Đã áp dụng!", - "failed": "thất bại", - "resetDone": "Đặt lại!", - "omnirouteConfiguredOpenAiCompatible": "OmniRoute được định cấu hình là nhà cung cấp tương thích với OpenAI", - "provider": "nhà cung cấp", - "model": "người mẫu", + "failed": "Thất bại", + "resetDone": "Đã đặt lại!", + "omnirouteConfiguredOpenAiCompatible": "OmniRoute được cấu hình là nhà cung cấp tương thích với OpenAI", + "provider": "Nhà cung cấp", + "model": "Mô hình", "providers": "Nhà cung cấp", "auth": "Xác thực", - "noApiKeysAvailable": "Không có khóa API nào", - "usingDefaultOmniroute": "Sử dụng mặc định: sk_omniroute", + "noApiKeysAvailable": "Không có khóa API nào khả dụng", + "usingDefaultOmniroute": "Đang sử dụng mặc định: sk_omniroute", "updateConfig": "Cập nhật cấu hình", "applyConfig": "Áp dụng cấu hình", - "noBackupsAvailable": "Không có bản sao lưu nào có sẵn.", + "noBackupsAvailable": "Không có bản sao lưu nào khả dụng.", "profileSaved": "Đã lưu hồ sơ \"{name}\"!", - "failedSaveProfile": "Không lưu được hồ sơ", - "profileActivated": "Hồ sơ đã được kích hoạt!", + "failedSaveProfile": "Không thể lưu hồ sơ", + "profileActivated": "Đã kích hoạt hồ sơ!", "failedActivateProfile": "Không thể kích hoạt hồ sơ", "profiles": "Hồ sơ", "savedProfiles": "Hồ sơ đã lưu", - "noProfilesYet": "Chưa có hồ sơ nào được lưu. Lưu cấu hình hiện tại dưới dạng hồ sơ bên dưới.", + "noProfilesYet": "Chưa có hồ sơ nào được lưu. Hãy lưu cấu hình hiện tại dưới dạng hồ sơ bên dưới.", "activate": "Kích hoạt", "deleteProfile": "Xóa hồ sơ", "profileNamePlaceholder": "Tên hồ sơ (ví dụ: Tài khoản cá nhân)", "saveCurrent": "Lưu hiện tại", - "codexAuthNotePrefix": "Công dụng của Codex", + "codexAuthNotePrefix": "Codex sử dụng", "codexAuthNoteMiddle": "với", - "codexAuthNoteSuffix": "Nhấp vào \"Áp dụng\" để tự động định cấu hình.", + "codexAuthNoteSuffix": "Nhấp vào \"Áp dụng\" để tự động cấu hình.", "claudeManualConfiguration": "Claude CLI - Cấu hình thủ công", "codexManualConfiguration": "Codex CLI - Cấu hình thủ công", "droidManualConfiguration": "Factory Droid - Cấu hình thủ công", "openClawManualConfiguration": "Open Claw - Cấu hình thủ công", "clineManualConfiguration": "Cấu hình thủ công Cline", - "kiloManualConfiguration": "Cấu hình thủ công mã Kilo", + "kiloManualConfiguration": "Cấu hình thủ công Kilo Code", "whenToUseLabel": "Khi nào nên sử dụng", "openToolDocs": "Mở tài liệu công cụ", "toolUseCases": { - "claude": "Sử dụng khi bạn muốn quy trình lập kế hoạch mạnh mẽ và các trình tái cấu trúc nhiều tệp dài với Mã Claude.", - "codex": "Sử dụng khi nhóm của bạn được chuẩn hóa trên các luồng OpenAI Codex CLI và xác thực dựa trên hồ sơ.", - "droid": "Sử dụng khi bạn cần một tác nhân đầu cuối nhẹ tập trung vào các vòng lặp thực thi lệnh và mã hóa nhanh.", - "openclaw": "Sử dụng khi bạn muốn một tác nhân mã hóa kiểu Open Claw nhưng được định tuyến thông qua các chính sách OmniRoute.", - "cline": "Sử dụng khi bạn định cấu hình các tác nhân mã hóa bên trong trình chỉnh sửa và muốn thiết lập có hướng dẫn với các mô hình OmniRoute.", + "claude": "Sử dụng khi bạn muốn có quy trình lập kế hoạch mạnh mẽ và tái cấu trúc nhiều tệp lớn với Claude Code.", + "codex": "Sử dụng khi nhóm của bạn đã chuẩn hóa theo các luồng OpenAI Codex CLI và xác thực dựa trên hồ sơ.", + "droid": "Sử dụng khi bạn cần một tác nhân dòng lệnh gọn nhẹ, tập trung vào việc viết mã nhanh và các vòng lặp thực thi lệnh.", + "openclaw": "Sử dụng khi bạn muốn một tác nhân lập trình kiểu Open Claw nhưng được định tuyến theo các chính sách của OmniRoute.", + "cline": "Sử dụng khi bạn cấu hình các tác nhân lập trình trong trình chỉnh sửa và muốn được hướng dẫn thiết lập với các mô hình OmniRoute.", "kilo": "Sử dụng khi quy trình làm việc của bạn phụ thuộc vào các lệnh Kilo Code và các chỉnh sửa lặp lại nhanh chóng.", - "cursor": "Sử dụng khi mã hóa bằng Con trỏ và bạn cần các mô hình tương thích với OpenAI tùy chỉnh thông qua OmniRoute.", - "continue": "Sử dụng khi chạy Tiếp tục trong IDE và bạn cần cấu hình nhà cung cấp dựa trên JSON di động.", - "opencode": "Sử dụng khi bạn thích chạy tác nhân gốc trên thiết bị đầu cuối và tự động hóa theo kịch bản thông qua OpenCode.", + "cursor": "Sử dụng khi lập trình trong Cursor và bạn cần các mô hình tương thích với OpenAI tùy chỉnh thông qua OmniRoute.", + "continue": "Sử dụng khi chạy Continue trong các IDE và bạn cần cấu hình nhà cung cấp dựa trên JSON có thể chuyển đổi.", + "opencode": "Sử dụng khi bạn thích chạy tác nhân trực tiếp trong terminal và tự động hóa bằng kịch bản qua OpenCode.", "kiro": "Sử dụng khi tích hợp Kiro và điều khiển định tuyến mô hình tập trung từ OmniRoute.", - "windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute.", - "antigravity": "Sử dụng khi lưu lượng truy cập AntiGravity/Kiro phải bị chặn thông qua MITM và được định tuyến đến OmniRoute.", - "copilot": "Sử dụng khi bạn muốn UX kiểu trò chuyện Copilot trong khi thực thi các khóa OmniRoute và quy tắc định tuyến.", - "amp": "Use when you want Amp CLI routed through OmniRoute with stable shorthand aliases and OpenAI-compatible setup.", - "qwen": "Use when you want Qwen Code CLI with OmniRoute-managed provider settings and multi-provider model access.", - "hermes": "Sử dụng khi bạn cần một trợ lý AI gốc thiết bị đầu cuối nhẹ để thực hiện các tác vụ nhanh chóng.", - "hermes-agent": "__MISSING__:Use when you need Hermes Agent (by Nousresearch) with default, delegation, vision and auxiliary models routed through OmniRoute.", + "windsurf": "Sử dụng khi bạn muốn có một IDE ưu tiên AI với các mô hình Codeium/Windsurf được định tuyến thông qua OmniRoute.", + "antigravity": "Sử dụng khi lưu lượng truy cập Antigravity/Kiro cần được chặn bắt qua MITM và định tuyến đến OmniRoute.", + "copilot": "Sử dụng khi bạn muốn trải nghiệm trò chuyện kiểu Copilot đồng thời áp dụng các khóa OmniRoute và quy tắc định tuyến.", + "amp": "Sử dụng khi bạn muốn các quy trình làm việc viết tắt của Amp nhưng vẫn cần áp dụng bí danh và quy tắc định tuyến của OmniRoute.", + "qwen": "Sử dụng khi bạn cần Alibaba Qwen Code CLI cho các tác vụ lập trình.", + "hermes": "Sử dụng khi bạn cần một trợ lý AI gọn nhẹ hoạt động trực tiếp trong terminal cho các tác vụ nhanh.", + "hermes-agent": "Sử dụng khi bạn cần Hermes Agent (do Nousresearch phát triển) với các mô hình mặc định, ủy quyền, xử lý hình ảnh và phụ trợ được định tuyến qua OmniRoute.", "custom": "Sử dụng để triển khai công cụ tùy chỉnh hoặc cấu hình chung tương thích với OpenAI." }, "toolDescriptions": { - "antigravity": "IDE chống trọng lực của Google với MITM", - "claude": "Mã Claude nhân loại CLI", + "antigravity": "Google Antigravity IDE với MITM", + "claude": "Anthropic Claude Code CLI", "codex": "OpenAI Codex CLI", - "droid": "Trợ lý AI Droid của nhà máy", - "openclaw": "Trợ lý AI móng vuốt mở", - "cline": "Trợ lý mã hóa Cline AI CLI", - "kilo": "Trợ lý AI Kilo Code CLI", - "cursor": "Trình chỉnh sửa mã AI con trỏ", - "continue": "Tiếp tục Trợ lý AI", - "opencode": "OpenCode AI coding agent (Terminal)", - "kiro": "Amazon Kiro — AI-powered IDE", - "windsurf": "Windsurf AI Code Editor", - "copilot": "GitHub Copilot AI Assistant", + "droid": "Trợ lý AI Factory Droid", + "openclaw": "Trợ lý AI Open Claw", + "cline": "CLI trợ lý lập trình Cline AI", + "kilo": "CLI trợ lý AI Kilo Code", + "cursor": "Trình chỉnh sửa mã AI Cursor", + "continue": "Trợ lý AI Continue", + "opencode": "Tác nhân lập trình AI OpenCode (Terminal)", + "kiro": "Amazon Kiro — IDE tích hợp AI", + "windsurf": "Trình chỉnh sửa mã AI Windsurf", + "copilot": "Trợ lý AI GitHub Copilot", "qwen": "Alibaba Qwen Code CLI", - "amp": "Sourcegraph Amp coding assistant CLI", - "hermes": "Trợ lý thiết bị đầu cuối Hermes AI", - "hermes-agent": "__MISSING__:Hermes Agent (by Nousresearch) - Advanced terminal AI with multi-model support (delegation, vision, compression, etc.)", - "custom": "Trình tạo cấu hình SDK hoặc CLI tương thích với OpenAI chung" + "amp": "CLI trợ lý lập trình Sourcegraph Amp", + "hermes": "Trợ lý AI terminal Hermes", + "hermes-agent": "Hermes Agent (bởi Nousresearch) - AI nâng cao cho terminal, hỗ trợ đa mô hình (ủy quyền, thị giác, nén, v.v.)", + "custom": "Trình tạo cấu hình chung cho CLI hoặc SDK tương thích với OpenAI" }, "guides": { "cursor": { "notes": { "0": "Yêu cầu tài khoản Cursor Pro để sử dụng tính năng này.", - "1": "Con trỏ định tuyến các yêu cầu thông qua máy chủ của chính nó, do đó điểm cuối cục bộ không được hỗ trợ. Vui lòng bật Cloud Endpoint trong Cài đặt." + "1": "Cursor định tuyến các yêu cầu thông qua máy chủ riêng, do đó không hỗ trợ endpoint cục bộ. Vui lòng bật Cloud Endpoint trong Cài đặt." }, "steps": { "1": { "title": "Mở Cài đặt", - "desc": "Đi tới Cài đặt -> Kiểu máy" + "desc": "Đi tới Cài đặt -> Mô hình" }, "2": { "title": "Kích hoạt API OpenAI", - "desc": "Bật tùy chọn \"Khóa API OpenAI\"" + "desc": "Bật tùy chọn \"OpenAI API key\"" }, "3": { "title": "URL cơ sở" @@ -2084,10 +2231,10 @@ }, "5": { "title": "Thêm mô hình tùy chỉnh", - "desc": "Nhấp vào \"Xem tất cả mẫu\" -> \"Thêm mẫu tùy chỉnh\"" + "desc": "Nhấp vào \"View All Model\" -> \"Add Custom Model\"" }, "6": { - "title": "Chọn mẫu" + "title": "Chọn mô hình" } } }, @@ -2095,64 +2242,64 @@ "steps": { "1": { "title": "Mở cấu hình", - "desc": "Mở tệp cấu hình Tiếp tục" + "desc": "Mở tệp cấu hình Continue" }, "2": { "title": "Khóa API" }, "3": { - "title": "Chọn mẫu" + "title": "Chọn mô hình" }, "4": { "title": "Thêm cấu hình mô hình", - "desc": "Thêm cấu hình sau vào mảng mô hình của bạn:" + "desc": "Thêm cấu hình sau vào mảng models của bạn:" } }, "notes": { - "0": "Tiếp tục sử dụng tệp cấu hình JSON." + "0": "Continue sử dụng tệp cấu hình JSON." } }, "opencode": { "steps": { "1": { - "title": "Install OpenCode", - "desc": "Install via npm: npm install -g opencode-ai" + "title": "Cài đặt OpenCode", + "desc": "Cài đặt qua npm: npm install -g opencode-ai" }, "2": { - "title": "API Key" + "title": "Khóa API" }, "3": { - "title": "Set Base URL", + "title": "Đặt URL cơ sở", "desc": "opencode config set baseUrl {baseUrl}" }, "4": { - "title": "Select Model" + "title": "Chọn mô hình" }, "5": { - "title": "Use Thinking Variant", - "desc": "For thinking models, run with --variant high/low/max (example command below)." + "title": "Sử dụng biến thể suy luận", + "desc": "Đối với các mô hình suy luận, hãy chạy với --variant high/low/max (lệnh ví dụ bên dưới)." } }, "notes": { "0": "OpenCode yêu cầu cấu hình khóa API.", - "1": "Đặt URL cơ sở cho điểm cuối OmniRoute của bạn." + "1": "Đặt URL cơ sở thành endpoint OmniRoute của bạn." } }, "kiro": { "steps": { "1": { - "title": "Open Kiro Settings", - "desc": "Go to Settings → AI Provider" + "title": "Mở Cài đặt Kiro", + "desc": "Đi tới Cài đặt → Nhà cung cấp AI" }, "2": { - "title": "Base URL", - "desc": "Paste your OmniRoute endpoint URL" + "title": "URL cơ sở", + "desc": "Dán URL endpoint của OmniRoute" }, "3": { - "title": "API Key" + "title": "Khóa API" }, "4": { - "title": "Select Model" + "title": "Chọn mô hình" } }, "notes": { @@ -2162,556 +2309,579 @@ "windsurf": { "steps": { "1": { - "title": "Open AI Settings", - "desc": "Click the AI Settings icon in Windsurf or go to Settings" + "title": "Mở Cài đặt AI", + "desc": "Nhấp vào biểu tượng Cài đặt AI trong Windsurf hoặc đi tới Cài đặt" }, "2": { - "title": "Add Custom Provider", - "desc": "Select \"Add custom provider\" (OpenAI-compatible)" + "title": "Thêm nhà cung cấp tùy chỉnh", + "desc": "Chọn \"Add custom provider\" (tương thích OpenAI)" }, "3": { - "title": "Base URL", + "title": "URL cơ sở", "desc": "http://127.0.0.1:20128/v1" }, "4": { - "title": "API Key", - "desc": "Select your OmniRoute API key" + "title": "Khóa API", + "desc": "Chọn khóa API OmniRoute của bạn" }, "5": { - "title": "Select Model", - "desc": "Choose a model from the dropdown" + "title": "Chọn mô hình", + "desc": "Chọn một mô hình từ danh sách thả xuống" } } } }, - "autoConfiguredTab": "Auto Configured Tab", - "toolCategoriesDesc": "Tool Categories Desc", - "allToolsTab": "All Tools Tab", - "guidedClientsTab": "Guided Clients Tab", - "mitmClientsTab": "Mitm Clients Tab", + "autoConfiguredTab": "Đã cấu hình tự động", + "toolCategoriesDesc": "Cấu hình các trợ lý lập trình AI để định tuyến qua OmniRoute", + "allToolsTab": "Tất cả công cụ", + "guidedClientsTab": "Ứng dụng khách có hướng dẫn", + "mitmClientsTab": "Ứng dụng khách MITM", "customCliTab": "CLI tùy chỉnh", - "toolCategories": "Tool Categories", + "toolCategories": "Danh mục công cụ", "visibleToolsCount": "{count} công cụ có sẵn", "customCliBuilderTitle": "Trình tạo CLI tương thích với OpenAI", - "customCliBuilderDescription": "Tạo các biến env và đoạn mã JSON cho bất kỳ CLI hoặc SDK nào chấp nhận URL cơ sở, khóa API và ID mô hình tương thích với OpenAI.", - "customCliNoModels": "Kết nối ít nhất một nhà cung cấp để điền vào bộ chọn mô hình.", + "customCliBuilderDescription": "Tạo các biến môi trường và đoạn mã JSON cho bất kỳ CLI hoặc SDK nào chấp nhận URL cơ sở, khóa API và ID mô hình tương thích với OpenAI.", + "customCliNoModels": "Kết nối ít nhất một nhà cung cấp để điền dữ liệu cho bộ chọn mô hình.", "customCliNameLabel": "Tên CLI", - "customCliNamePlaceholder": "ví dụ: CLI nhóm của tôi", + "customCliNamePlaceholder": "ví dụ: CLI của nhóm tôi", "customCliDefaultModelLabel": "Mô hình mặc định", - "customCliDefaultModelHelp": "Sử dụng bất kỳ ID hoặc kết hợp mô hình OmniRoute nào. Hầu hết các CLI tương thích với OpenAI chỉ cần URL cơ sở /v1 cộng với chuỗi mô hình.", - "customCliKeyHelper": "Để cài đặt cục bộ OmniRoute có thể sử dụng sk_omniroute. Ở chế độ đám mây, hãy chọn một trong các khóa API quản lý của bạn.", + "customCliDefaultModelHelp": "Sử dụng bất kỳ ID mô hình hoặc combo nào của OmniRoute. Hầu hết các CLI tương thích với OpenAI chỉ cần URL cơ sở /v1 và một chuỗi mô hình.", + "customCliKeyHelper": "Đối với các bản cài đặt cục bộ, OmniRoute có thể sử dụng sk_omniroute. Ở chế độ đám mây, hãy chọn một trong các khóa API quản lý của bạn.", "customCliAliasMappingsLabel": "Ánh xạ bí danh", - "customCliAliasMappingsHelp": "Bí danh trợ giúp tùy chọn cho các tập lệnh bao bọc hoặc tệp cấu hình muốn có tên tốc ký ổn định.", + "customCliAliasMappingsHelp": "Các bí danh hỗ trợ tùy chọn cho tập lệnh bao bọc hoặc tệp cấu hình cần tên rút gọn nhất quán.", "customCliAddAlias": "Thêm bí danh", - "customCliNoMappings": "Chưa có ánh xạ bí danh nào. Thêm một tên nếu trình bao bọc hoặc tập lệnh nhóm của bạn sử dụng tên ngắn ổn định.", - "customCliAliasPlaceholder": "ví dụ: đánh giá", + "customCliNoMappings": "Chưa có ánh xạ bí danh nào. Hãy thêm một bí danh nếu tập lệnh bao bọc hoặc tập lệnh của nhóm bạn sử dụng tên rút gọn nhất quán.", + "customCliAliasPlaceholder": "ví dụ: review", "customCliTargetModelLabel": "Mô hình mục tiêu", - "customCliEndpointHintLabel": "Cách nối dây điểm cuối", - "customCliEndpointHint": "Trỏ bất kỳ ứng dụng khách nào tương thích với OpenAI tới URL cơ sở OmniRoute /v1. Điểm cuối hoàn thành cuộc trò chuyện thô là {endpoint}. Sử dụng khối JSON khi công cụ muốn một đối tượng nhà cung cấp hoặc tập lệnh env khi nó đọc các biến OPENAI_*.", - "customCliEnvBlockTitle": "Đoạn mã Env/shell", - "customCliJsonBlockTitle": "Khối JSON của nhà cung cấp", - "copilotConfigGenerator": "Trình tạo cấu hình phi công phụ GitHub", + "customCliEndpointHintLabel": "Cách cấu hình endpoint", + "customCliEndpointHint": "Cấu hình bất kỳ ứng dụng khách tương thích với OpenAI nào sử dụng URL cơ sở OmniRoute /v1. Endpoint chat completions thô là {endpoint}. Sử dụng khối JSON khi công cụ yêu cầu một đối tượng nhà cung cấp hoặc tập lệnh môi trường khi công cụ đọc các biến môi trường OPENAI_*.", + "customCliEnvBlockTitle": "Đoạn mã môi trường / shell", + "customCliJsonBlockTitle": "Khối JSON nhà cung cấp", + "copilotConfigGenerator": "Trình tạo cấu hình GitHub Copilot", "copilotApiKey": "Khóa API", - "copilotFilterModelsPlaceholder": "Mô hình lọc...", - "copilotMaxInputTokens": "Mã thông báo đầu vào tối đa", - "copilotMaxOutputTokens": "Mã thông báo đầu ra tối đa", + "copilotFilterModelsPlaceholder": "Lọc mô hình...", + "copilotMaxInputTokens": "Token đầu vào tối đa", + "copilotMaxOutputTokens": "Token đầu ra tối đa", "copilotToolCalling": "Gọi công cụ", "copilotPasteInto": "Dán vào:", - "wireApiChatCompletions": "Số lần hoàn thành trò chuyện (/chat/hoàn thành)", - "wireApiResponses": "API phản hồi (/ phản hồi)", - "reasoningEffort": "__MISSING__:Reasoning effort for {model}", - "reasoningEffortDefault": "__MISSING__:Default", - "reasoningEffortHint": "__MISSING__:Default preserves the reasoning effort sent by the agent", + "wireApiChatCompletions": "Chat Completions (/chat/completions)", + "wireApiResponses": "Responses API (/responses)", + "reasoningEffort": "Mức suy luận cho {model}", + "reasoningEffortDefault": "Mặc định", + "reasoningEffortHint": "Mặc định sẽ giữ nguyên mức suy luận do agent gửi", "reasoningEffortTier": { - "none": "__MISSING__:None", - "low": "__MISSING__:Low", - "medium": "__MISSING__:Medium", - "high": "__MISSING__:High", - "xhigh": "__MISSING__:XHigh" + "none": "Không có", + "low": "Thấp", + "medium": "Trung bình", + "high": "Cao", + "xhigh": "Rất cao" } }, "combos": { "title": "Combo", - "description": "Tạo các tổ hợp mô hình với hỗ trợ định tuyến và dự phòng có trọng số", + "description": "Tạo các combo mô hình với hỗ trợ định tuyến có trọng số và dự phòng", "autoCatalogTitle": "Danh mục định tuyến tự động", "autoCatalogTemplateCount": "{count} mẫu", - "autoCatalogDescription": "Các tổ hợp tự động/* tích hợp được giải quyết linh hoạt từ các nhà cung cấp được kết nối. Sử dụng bất kỳ ID nào trong số này làm trường mô hình — không cần thiết lập.", + "autoCatalogDescription": "Các combo auto/* tích hợp sẵn được phân giải động từ các nhà cung cấp đã kết nối. Sử dụng bất kỳ ID nào trong số này làm trường mô hình — không cần thiết lập.", "autoCatalogExpand": "Mở rộng danh mục định tuyến tự động", "autoCatalogCollapse": "Thu gọn danh mục định tuyến tự động", - "createCombo": "Tạo tổ hợp", - "editCombo": "Chỉnh sửa kết hợp", - "deleteCombo": "Xóa tổ hợp", + "createCombo": "Tạo Combo", + "editCombo": "Chỉnh sửa combo", + "deleteCombo": "Xóa combo", "noModels": "Không có mô hình", - "noModelsYet": "Chưa có mô hình nào được thêm vào", + "noModelsYet": "Chưa có mô hình nào được thêm", "addModel": "Thêm mô hình", - "addModelToCombo": "Thêm Model vào Combo", + "addModelToCombo": "Thêm mô hình vào combo", "routingStrategy": "Chiến lược định tuyến", "maxRetries": "Số lần thử lại tối đa", "timeout": "Thời gian chờ (ms)", - "healthcheck": "Kiểm tra sức khỏe", - "priority": "Ưu tiên", + "healthcheck": "Kiểm tra tình trạng", + "priority": "Độ ưu tiên", "fallback": "Dự phòng", - "roundRobin": "Vòng Robin", + "roundRobin": "Luân phiên", "random": "Ngẫu nhiên", - "leastLatency": "Độ trễ ít nhất", - "comboName": "Tên kết hợp", - "comboNamePlaceholder": "combo của tôi", - "deleteConfirm": "Xóa tổ hợp này?", + "leastLatency": "Độ trễ thấp nhất", + "comboName": "Tên combo", + "comboNamePlaceholder": "my-combo", + "deleteConfirm": "Xóa combo này?", "noCombosYet": "Chưa có combo nào", - "comboCreated": "Combo được tạo thành công", - "comboUpdated": "Combo được cập nhật thành công", - "comboDeleted": "Đã xóa kết hợp", - "failedCreate": "Không tạo được kết hợp", - "failedUpdate": "Không thể cập nhật kết hợp", - "errorCreating": "Lỗi tạo combo", - "errorUpdating": "Lỗi cập nhật kết hợp", - "errorDeleting": "Lỗi xóa kết hợp", + "comboCreated": "Tạo combo thành công", + "comboUpdated": "Cập nhật combo thành công", + "comboDeleted": "Đã xóa combo", + "failedCreate": "Không thể tạo combo", + "failedUpdate": "Không thể cập nhật combo", + "errorCreating": "Lỗi khi tạo combo", + "errorUpdating": "Lỗi khi cập nhật combo", + "errorDeleting": "Lỗi khi xóa combo", "testFailed": "Yêu cầu kiểm tra không thành công", - "failedToggle": "Không thể chuyển đổi kết hợp", + "failedToggle": "Không thể bật/tắt combo", "testResults": "Kết quả kiểm tra — {name}", - "resolvedBy": "Đã giải quyết bởi:", + "resolvedBy": "Được giải quyết bởi:", "more": "+{count} khác", "reqs": "yêu cầu", - "success": "sự thành công", - "proxyConfigured": "Đã định cấu hình proxy", - "copyComboName": "Sao chép tên tổ hợp", - "enableCombo": "Bật kết hợp", - "disableCombo": "Tắt kết hợp", - "testCombo": "Kết hợp thử nghiệm", - "duplicate": "trùng lặp", + "success": "thành công", + "proxyConfigured": "Đã cấu hình proxy", + "copyComboName": "Sao chép tên combo", + "enableCombo": "Bật combo", + "disableCombo": "Tắt combo", + "testCombo": "Kiểm tra combo", + "duplicate": "Nhân bản", "proxyConfig": "Cấu hình proxy", "nameRequired": "Tên là bắt buộc", - "nameInvalid": "Chỉ các chữ cái, số, -, _, / và . được phép", - "nameHint": "Các chữ cái, số, -, _, / và . được phép", - "priorityDesc": "Dự phòng tuần tự: thử mô hình 1 trước, sau đó đến mô hình 2, v.v.", - "weightedDesc": "Phân phối lưu lượng truy cập theo phần trăm trọng lượng với dự phòng", - "roundRobinDesc": "Phân phối vòng tròn: mỗi yêu cầu sẽ chuyển sang mô hình tiếp theo trong vòng quay", - "contextRelay": "Context Relay", - "contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate", - "randomDesc": "Lựa chọn ngẫu nhiên thống nhất, sau đó dự phòng cho các mô hình còn lại", + "nameInvalid": "Chỉ cho phép chữ cái, chữ số, -, _, / và .", + "nameHint": "Cho phép chữ cái, chữ số, -, _, / và .", + "priorityDesc": "Dự phòng tuần tự: thử mô hình 1 trước, sau đó đến 2, v.v.", + "weightedDesc": "Phân phối lưu lượng theo phần trăm trọng số kèm dự phòng", + "roundRobinDesc": "Phân phối vòng tròn: mỗi yêu cầu sẽ chuyển sang mô hình tiếp theo theo lượt", + "contextRelay": "Chuyển tiếp ngữ cảnh", + "contextRelayDesc": "Bảo toàn tính liên tục của phiên bằng các bản tóm tắt bàn giao khi tài khoản xoay vòng", + "randomDesc": "Lựa chọn ngẫu nhiên đồng đều, sau đó dự phòng sang các mô hình còn lại", "leastUsedDesc": "Chọn mô hình có ít yêu cầu nhất, cân bằng tải theo thời gian", - "costOptimizedDesc": "Hướng tới mô hình rẻ nhất trước tiên dựa trên giá cả", - "resetAware": "Đặt lại RR nhận biết", - "resetAwareDesc": "Cân bằng hạn ngạch còn lại với số lần đặt lại 5 giờ và hàng tuần, sau đó tính điểm tương tự theo vòng tròn", - "strictRandom": "Strict Random", - "strictRandomDesc": "Shuffle deck — uses each model once before reshuffling", - "models": "Người mẫu", + "costOptimizedDesc": "Định tuyến đến mô hình có giá thấp nhất trước dựa trên mức giá", + "resetAware": "RR nhận biết đặt lại", + "resetAwareDesc": "Cân bằng hạn ngạch còn lại với các mốc đặt lại sau 5 giờ và hằng tuần, sau đó xoay vòng các mô hình có điểm số tương tự", + "strictRandom": "Ngẫu nhiên nghiêm ngặt", + "strictRandomDesc": "Trộn bài — sử dụng mỗi mô hình một lần trước khi trộn lại", + "models": "Mô hình", "autoBalance": "Tự động cân bằng", "advancedSettings": "Cài đặt nâng cao", "retryDelay": "Độ trễ thử lại (ms)", - "concurrencyPerModel": "Đồng thời / Mô hình", - "queueTimeout": "Hết thời gian xếp hàng (ms)", - "contextRelayHandoffThreshold": "Handoff Threshold", - "contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.", - "contextRelayMaxMessages": "Max Messages For Summary", - "contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.", - "contextRelaySummaryModel": "Summary Model", - "contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.", - "contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.", - "advancedHint": "Để trống để sử dụng mặc định chung. Những cài đặt này ghi đè lên mỗi nhà cung cấp.", + "concurrencyPerModel": "Số yêu cầu đồng thời / Mô hình", + "queueTimeout": "Thời gian chờ hàng đợi (ms)", + "contextRelayHandoffThreshold": "Ngưỡng bàn giao", + "contextRelayHandoffThresholdHelp": "Khi mức sử dụng hạn ngạch đạt đến ngưỡng này, OmniRoute sẽ tạo một bản tóm tắt bàn giao có cấu trúc trước khi tài khoản đang hoạt động bị cạn kiệt.", + "contextRelayMaxMessages": "Số lượng tin nhắn tối đa cho bản tóm tắt", + "contextRelayMaxMessagesHelp": "Giới hạn lượng lịch sử gần đây được nén vào bản tóm tắt chuyển tiếp.", + "contextRelaySummaryModel": "Mô hình tóm tắt", + "contextRelaySummaryModelHelp": "Mô hình ghi đè tùy chọn chỉ dùng để tạo bản tóm tắt bàn giao. Để trống để sử dụng lại mô hình combo đang hoạt động.", + "contextRelayProviderNote": "Context Relay hiện đang tạo bàn giao cho việc xoay vòng tài khoản Codex. Hãy kết hợp nó với nhiều tài khoản của cùng một nhà cung cấp để có tính liên tục tốt nhất.", + "advancedHint": "Để trống để sử dụng các giá trị mặc định toàn cục. Các cài đặt này sẽ ghi đè cài đặt của từng nhà cung cấp.", "failoverBeforeRetry": "Chuyển đổi dự phòng trước khi thử lại", - "maxSetRetries": "Số lần thử lại tập hợp tối đa", - "setRetryDelayMs": "Đặt độ trễ thử lại (ms)", + "maxSetRetries": "Số lần thử lại tối đa cho tập hợp", + "setRetryDelayMs": "Độ trễ thử lại của tập hợp (ms)", "moveUp": "Di chuyển lên", "moveDown": "Di chuyển xuống", "removeModel": "Xóa", "saving": "Đang lưu...", "weighted": "Có trọng số", "leastUsed": "Ít được sử dụng nhất", - "costOpt": "Lựa chọn chi phí", - "strategyGuideTitle": "How to use this strategy", - "strategyGuideWhen": "When to use", - "strategyGuideAvoid": "Avoid when", - "strategyGuideExample": "Example", + "costOpt": "Tối ưu hóa chi phí", + "strategyGuideTitle": "Cách sử dụng chiến lược này", + "strategyGuideWhen": "Khi nào nên sử dụng", + "strategyGuideAvoid": "Không nên sử dụng khi", + "strategyGuideExample": "Ví dụ", "strategyGuide": { "priority": { - "when": "You have one preferred model and only want fallback on failure.", - "avoid": "You need request distribution across models.", - "example": "Primary coding model with cheaper backup for outages." + "when": "Bạn có một mô hình ưa thích và chỉ muốn dự phòng khi xảy ra lỗi.", + "avoid": "Bạn cần phân bổ yêu cầu giữa các mô hình.", + "example": "Mô hình lập trình chính kèm theo mô hình sao lưu rẻ hơn khi xảy ra sự cố ngừng hoạt động." }, "weighted": { - "when": "You need controlled traffic split across models.", - "avoid": "You cannot maintain accurate weights over time.", - "example": "80% stable model + 20% canary model rollout." + "when": "Bạn cần phân chia lưu lượng truy cập có kiểm soát giữa các mô hình.", + "avoid": "Bạn không thể duy trì trọng số chính xác theo thời gian.", + "example": "80% mô hình ổn định + triển khai mô hình canary cho 20%." }, "round-robin": { - "when": "You want predictable and even distribution.", - "avoid": "Models differ too much in latency or cost.", - "example": "Same model on multiple accounts to spread throughput." + "when": "Bạn muốn phân bổ đồng đều và có thể dự đoán trước.", + "avoid": "Các mô hình quá khác biệt về độ trễ hoặc chi phí.", + "example": "Sử dụng cùng một mô hình trên nhiều tài khoản để phân bổ thông lượng." }, "random": { - "when": "You want simple distribution with minimal setup.", - "avoid": "You need strict traffic guarantees.", - "example": "Quick prototyping with equivalent models." + "when": "Bạn muốn phân bổ đơn giản với thiết lập tối thiểu.", + "avoid": "Bạn cần các đảm bảo nghiêm ngặt về lưu lượng truy cập.", + "example": "Tạo mẫu nhanh với các mô hình tương đương." }, "least-used": { - "when": "You want adaptive balancing based on live demand.", - "avoid": "Traffic is too low to benefit from usage balancing.", - "example": "Mixed workloads where one model often gets overloaded." + "when": "Bạn muốn cân bằng thích ứng dựa trên nhu cầu thực tế.", + "avoid": "Lưu lượng truy cập quá thấp để hưởng lợi từ việc cân bằng mức sử dụng.", + "example": "Khối lượng công việc hỗn hợp, trong đó một mô hình thường bị quá tải." }, "cost-optimized": { - "when": "Cost reduction is your top priority.", - "avoid": "Pricing data is missing or outdated.", - "example": "Background or batch jobs where lower cost is preferred." + "when": "Giảm chi phí là ưu tiên hàng đầu của bạn.", + "avoid": "Dữ liệu giá bị thiếu hoặc lỗi thời.", + "example": "Các tác vụ chạy ngầm hoặc tác vụ hàng loạt ưu tiên chi phí thấp hơn." }, "reset-aware": { - "when": "Bạn định tuyến trên nhiều tài khoản bằng phép đo từ xa hạn ngạch và các khoảng thời gian đặt lại khác nhau.", - "avoid": "Đo từ xa hạn ngạch không khả dụng cho hầu hết các tài khoản.", - "example": "Ưu tiên đặt lại tài khoản hàng tuần 60% vào ngày mai hơn là đặt lại tài khoản 80% sau này." + "when": "Bạn định tuyến giữa nhiều tài khoản bằng dữ liệu đo từ xa về hạn ngạch và các chu kỳ đặt lại khác nhau.", + "avoid": "Dữ liệu đo từ xa về hạn ngạch không khả dụng cho hầu hết các tài khoản.", + "example": "Ưu tiên tài khoản có hạn ngạch theo tuần đang ở mức 60% và sẽ được đặt lại vào ngày mai hơn tài khoản ở mức 80% sẽ được đặt lại muộn hơn." }, "strict-random": { - "when": "Use when you want perfectly even spread — each model used once before repeating.", - "avoid": "Avoid when models have different quality or latency and order matters.", - "example": "Example: Multiple accounts of the same model to distribute usage evenly." + "when": "Sử dụng khi bạn muốn phân bổ hoàn toàn đồng đều — mỗi mô hình được sử dụng một lần trước khi lặp lại.", + "avoid": "Tránh khi các mô hình có chất lượng hoặc độ trễ khác nhau và thứ tự sử dụng là quan trọng.", + "example": "Ví dụ: Nhiều tài khoản của cùng một mô hình để phân bổ mức sử dụng đồng đều." }, "p2c": { - "when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.", - "avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.", - "example": "Example: High-throughput inference across 4+ equivalent model endpoints." + "when": "Sử dụng khi bạn muốn lựa chọn có độ trễ thấp bằng thuật toán Power-of-Two-Choices.", + "avoid": "Tránh đối với các tổ hợp nhỏ có từ 2 mô hình trở xuống — không đem lại lợi ích so với round-robin.", + "example": "Ví dụ: Suy luận thông lượng cao trên 4 endpoint mô hình tương đương trở lên." }, "context-relay": { - "when": "Use when long sessions must survive account rotation without losing the working context.", - "avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.", - "example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion." + "when": "Sử dụng khi các phiên dài cần duy trì qua việc luân chuyển tài khoản mà không làm mất ngữ cảnh làm việc.", + "avoid": "Tránh khi việc chuyển đổi tài khoản hiếm khi xảy ra hoặc khi bạn không muốn có thêm các yêu cầu tóm tắt bổ sung.", + "example": "Ví dụ: Các phiên Codex luân chuyển qua nhiều tài khoản khi gần hết hạn ngạch." }, "fill-first": { "when": "Sử dụng khi bạn muốn sử dụng hết hạn ngạch của một nhà cung cấp trước khi chuyển sang nhà cung cấp tiếp theo.", "avoid": "Tránh khi bạn cần cân bằng tải ở cấp độ yêu cầu giữa các nhà cung cấp.", - "example": "Ví dụ: Sử dụng tất cả khoản tín dụng Deepgram $200 trước khi quay lại Groq." + "example": "Ví dụ: Sử dụng hết 200 USD tín dụng Deepgram trước khi chuyển sang Groq theo phương án dự phòng." }, "auto": { - "when": "Sử dụng khi bạn cần định tuyến tính điểm đa yếu tố dựa trên chi phí, độ trễ và chất lượng.", - "avoid": "Tránh khi bạn cần thứ tự ưu tiên nghiêm ngặt hoặc sự kiên trì lịch sử.", + "when": "Sử dụng khi bạn cần định tuyến bằng tính điểm đa yếu tố dựa trên chi phí, độ trễ và chất lượng.", + "avoid": "Tránh khi bạn cần thứ tự ưu tiên nghiêm ngặt hoặc lưu giữ dữ liệu lịch sử.", "example": "Ví dụ: Cân bằng yêu cầu giữa các mô hình có điểm mạnh khác nhau." }, "lkgp": { "when": "Sử dụng khi bạn muốn định tuyến dựa trên hiệu suất và tỷ lệ thành công trước đây.", "avoid": "Tránh khi dữ liệu lịch sử bị hạn chế hoặc không đáng tin cậy.", - "example": "Ví dụ: Hướng tới những người mẫu có thành tích tốt về các nhiệm vụ cụ thể." + "example": "Ví dụ: Định tuyến đến các mô hình có lịch sử hoạt động tốt cho các nhiệm vụ cụ thể." }, "context-optimized": { "when": "Sử dụng khi bạn cần tối ưu hóa việc sử dụng cửa sổ ngữ cảnh trên các mô hình.", - "avoid": "Tránh khi các mô hình có độ dài bối cảnh tương tự hoặc các nhiệm vụ đơn giản.", - "example": "Ví dụ: Phân phối các cuộc hội thoại dài trên các mô hình có cửa sổ ngữ cảnh lớn hơn." + "avoid": "Tránh khi các mô hình có độ dài ngữ cảnh tương tự hoặc các tác vụ đơn giản.", + "example": "Ví dụ: Phân phối các cuộc hội thoại dài giữa các mô hình có cửa sổ ngữ cảnh lớn hơn." } }, "advancedHelp": { - "maxRetries": "How many retries are attempted before failing a request.", - "retryDelay": "Initial wait between retries. Higher values reduce burst pressure.", - "timeout": "Maximum request duration before aborting.", - "healthcheck": "Skips unhealthy models/providers from routing decisions.", - "concurrencyPerModel": "Max simultaneous requests allowed per model in round-robin.", - "queueTimeout": "How long a request can wait in queue before timing out.", - "failoverBeforeRetry": "Khi được bật, mọi lỗi ngược dòng sẽ kích hoạt chuyển đổi dự phòng ngay lập tức sang mục tiêu kết hợp tiếp theo, bỏ qua tất cả các lần thử lại và URL dự phòng.", - "maxSetRetries": "Số lần thử lại toàn bộ mục tiêu khi mọi mục tiêu đều thất bại. 0 = không thử lại mức đã đặt.", - "setRetryDelayMs": "Độ trễ giữa các lần thử lại ở mức đã đặt, giúp các vấn đề nhất thời có thời gian giải quyết." + "maxRetries": "Số lần thử lại trước khi yêu cầu bị xem là thất bại.", + "retryDelay": "Thời gian chờ ban đầu giữa các lần thử lại. Giá trị cao hơn giúp giảm áp lực do các đợt yêu cầu dồn dập.", + "timeout": "Thời lượng tối đa của yêu cầu trước khi bị hủy.", + "healthcheck": "Bỏ qua các mô hình/nhà cung cấp không hoạt động bình thường khi đưa ra quyết định định tuyến.", + "concurrencyPerModel": "Số yêu cầu đồng thời tối đa được phép cho mỗi mô hình trong định tuyến luân phiên.", + "queueTimeout": "Thời gian tối đa một yêu cầu có thể chờ trong hàng đợi trước khi hết thời gian chờ.", + "failoverBeforeRetry": "Khi được bật, bất kỳ lỗi nào từ thượng nguồn cũng sẽ kích hoạt chuyển đổi dự phòng ngay lập tức sang mục tiêu combo tiếp theo, bỏ qua tất cả các lần thử lại và URL dự phòng.", + "maxSetRetries": "Số lần thử lại toàn bộ tập hợp mục tiêu khi mọi mục tiêu đều thất bại. 0 = không thử lại ở cấp tập hợp.", + "setRetryDelayMs": "Độ trễ giữa các lần thử lại ở cấp tập hợp, giúp các sự cố tạm thời có thời gian tự khắc phục.", + "disableSessionStickiness": "Rotate to a different connection on every request instead of pinning a whole conversation to one connection by the first-message hash. Overrides the global default. Leave on Inherit to preserve prompt-cache hits for multi-turn chats." }, - "templatesTitle": "Quick templates", - "templatesDescription": "Apply a starting profile, then adjust models and config.", - "templateApply": "Apply template", - "templateHighAvailability": "High availability", - "templateHighAvailabilityDesc": "Priority routing with health checks and safe retries.", - "templateCostSaver": "Cost saver", - "templateCostSaverDesc": "Cost-optimized routing for budget-first workloads.", - "templateBalanced": "Balanced load", - "templateBalancedDesc": "Least-used routing to spread demand over time.", - "usageGuideHide": "Hide", - "usageGuideDontShowAgain": "Don't show again", - "usageGuideShow": "Show guide", - "quickTestTitle": "Combo ready to validate", - "quickTestDescription": "Run a test now to confirm fallback and latency behavior.", - "testNow": "Test now", - "pricingCoverage": "Pricing coverage", - "pricingCoverageHint": "Cost-optimized works best when all combo models have pricing.", - "pricingAvailable": "Pricing available", - "pricingMissing": "No pricing", - "pricingAvailableShort": "priced", - "pricingMissingShort": "no-price", - "warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.", - "warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.", - "warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.", - "filterAll": "All", - "filterIntelligent": "Intelligent", - "filterDeterministic": "Deterministic", - "filterEmptyTitle": "No combos match this strategy filter.", - "filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.", - "filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.", - "readinessTitle": "Sẵn sàng để lưu?", - "readinessDescription": "Xem lại danh sách kiểm tra trước khi tạo hoặc cập nhật kết hợp này.", - "readinessCheckName": "Tên kết hợp là hợp lệ", - "readinessCheckModels": "Ít nhất một mô hình được chọn", + "templatesTitle": "Mẫu nhanh", + "templatesDescription": "Áp dụng một cấu hình ban đầu, sau đó điều chỉnh các mô hình và cấu hình.", + "templateApply": "Áp dụng mẫu", + "templateHighAvailability": "Tính sẵn sàng cao", + "templateHighAvailabilityDesc": "Định tuyến ưu tiên với kiểm tra tình trạng và thử lại an toàn.", + "templateCostSaver": "Tiết kiệm chi phí", + "templateCostSaverDesc": "Định tuyến tối ưu hóa chi phí cho các khối lượng công việc ưu tiên ngân sách.", + "templateBalanced": "Cân bằng tải", + "templateBalancedDesc": "Định tuyến theo mức sử dụng ít nhất để phân bổ nhu cầu theo thời gian.", + "usageGuideHide": "Ẩn", + "usageGuideDontShowAgain": "Không hiển thị lại", + "usageGuideShow": "Hiển thị hướng dẫn", + "quickTestTitle": "Combo đã sẵn sàng để xác thực", + "quickTestDescription": "Chạy thử nghiệm ngay để xác nhận hành vi dự phòng và độ trễ.", + "testNow": "Thử nghiệm ngay", + "pricingCoverage": "Phạm vi thông tin giá", + "pricingCoverageHint": "Tối ưu hóa chi phí hoạt động tốt nhất khi tất cả các mô hình trong combo đều có thông tin giá cả.", + "pricingAvailable": "Đã có thông tin giá", + "pricingMissing": "Chưa có thông tin giá", + "pricingAvailableShort": "đã định giá", + "pricingMissingShort": "chưa định giá", + "warningRoundRobinSingleModel": "Định tuyến luân phiên hữu ích nhất khi có ít nhất 2 mô hình.", + "warningCostOptimizedPartialPricing": "Chỉ có {priced} trên {total} mô hình có thông tin giá. Việc định tuyến có thể chỉ tính đến chi phí một phần.", + "warningCostOptimizedNoPricing": "Không tìm thấy dữ liệu giá cho combo này. Định tuyến tối ưu hóa chi phí có thể không như mong đợi.", + "filterAll": "Tất cả", + "filterIntelligent": "Thông minh", + "filterDeterministic": "Có tính xác định", + "filterEmptyTitle": "Không có combo nào khớp với bộ lọc chiến lược này.", + "filterEmptyIntelligentDescription": "Tạo một combo tự động hoặc LKGP để hiển thị dữ liệu trên bảng điều khiển định tuyến thông minh.", + "filterEmptyDeterministicDescription": "Hiện tại chỉ tồn tại các combo tự động và LKGP. Vui lòng chuyển lại về Tất cả hoặc tạo một combo xác định.", + "readinessTitle": "Sẵn sàng lưu?", + "readinessDescription": "Xem lại danh sách kiểm tra trước khi tạo hoặc cập nhật combo này.", + "readinessCheckName": "Tên combo hợp lệ", + "readinessCheckModels": "Đã chọn ít nhất một mô hình", "readinessCheckWeights": "Tổng trọng số là 100%", - "readinessCheckWeightsOptional": "Không cần quy định trọng lượng", - "readinessCheckPricing": "Dữ liệu giá cả có sẵn", - "readinessCheckPricingOptional": "Quy tắc đặt giá không bắt buộc", - "saveBlockedTitle": "Lưu bị chặn cho đến khi các mục sau được khắc phục:", - "saveBlockName": "Xác định tên kết hợp.", + "readinessCheckWeightsOptional": "Không yêu cầu quy tắc trọng số", + "readinessCheckPricing": "Đã có sẵn dữ liệu giá cả", + "readinessCheckPricingOptional": "Không yêu cầu quy tắc giá cả", + "saveBlockedTitle": "Không thể lưu cho đến khi khắc phục các mục sau:", + "saveBlockName": "Đặt tên cho combo.", "saveBlockModels": "Thêm ít nhất một mô hình.", "saveBlockWeighted": "Đặt trọng số thành 100% (hiện tại: {total}%).", "saveBlockPricing": "Thêm giá cho ít nhất một mô hình hoặc chọn một chiến lược khác.", - "recommendationsLabel": "Recommended setup", - "applyRecommendations": "Apply recommendations", - "recommendationsUpdated": "Recommendations updated for {strategy}.", - "recommendationsApplied": "Recommendations applied to this combo.", - "intelligentPanelTitle": "Intelligent Routing Dashboard", - "intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.", - "configOnlyStatus": "__MISSING__:Configuration View", - "configOnlyHint": "__MISSING__:This panel shows routing inputs only. Live breaker state is available on the Health page.", - "routingInputs": "__MISSING__:Routing Inputs", - "routingInputsHint": "__MISSING__:Mode pack and weighting stay here; breaker runtime state stays on the Health page.", - "emailVisibilityHint": "__MISSING__:Account emails here follow the global privacy toggle.", - "emailVisibilityTooltip": "__MISSING__:Use the eye icon to reveal or hide account emails globally across combos, providers and quota screens.", - "manualModel": "__MISSING__:Manual model", - "manualModelInvalid": "__MISSING__:Enter a model as provider/model.", - "manualModelUnknownProvider": "__MISSING__:Unknown provider prefix.", - "builderDynamicAccountShort": "__MISSING__:Dynamic account", - "builderNeedValidName": "__MISSING__:Define a valid combo name before continuing.", - "statusOverview": "Status Overview", - "normalOperation": "Normal Operation", - "allProvidersHealthy": "Providers are reporting healthy routing conditions.", - "incidentMode": "Incident Mode", - "highCircuitBreakerRate": "High circuit breaker trip rate detected.", - "activeModePack": "Active Mode Pack", - "modePackUpdated": "Mode pack updated to {pack}.", - "modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.", - "providerScores": "Provider Scores", - "allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.", - "excludedProviders": "Excluded Providers", - "excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.", - "noExcludedProviders": "No providers are currently excluded.", - "cooldownMinutes": "Cooldown: {minutes}m", - "builderIntelligentTitle": "Intelligent Routing Configuration", - "builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.", - "candidatePoolLabel": "Candidate Pool", - "candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.", - "candidatePoolEmpty": "No active providers available yet.", - "candidatePoolAllProviders": "All providers", - "modePackLabel": "Mode Pack", - "routerStrategyLabel": "Router Strategy", - "strategyRules": "Rules (6-Factor Scoring)", - "explorationRateLabel": "Exploration Rate", - "explorationRateHint": "{percent}% of requests can explore non-optimal providers.", - "budgetCapLabel": "Budget Cap (USD / request)", - "budgetCapPlaceholder": "No limit", - "advancedWeightsTitle": "Advanced: Scoring Weights", - "weightQuota": "Quota", - "weightHealth": "Health", - "weightCostInv": "Cost", - "weightLatencyInv": "Latency", - "weightTaskFit": "Task Fit", - "weightStability": "Stability", - "weightTierPriority": "Tier", - "reviewIntelligentTitle": "Intelligent Routing Config", + "recommendationsLabel": "Cấu hình đề xuất", + "applyRecommendations": "Áp dụng các đề xuất", + "recommendationsUpdated": "Các đề xuất đã được cập nhật cho {strategy}.", + "recommendationsApplied": "Các đề xuất đã được áp dụng cho combo này.", + "intelligentPanelTitle": "Bảng điều khiển định tuyến thông minh", + "intelligentPanelDesc": "Điểm số theo thời gian thực và trạng thái hoạt động của combo định tuyến tự động này.", + "configOnlyStatus": "Chế độ xem cấu hình", + "configOnlyHint": "Bảng này chỉ hiển thị các đầu vào định tuyến. Trạng thái hiện tại của bộ ngắt mạch có trên trang Tình trạng.", + "routingInputs": "Đầu vào định tuyến", + "routingInputsHint": "Gói chế độ và trọng số được hiển thị ở đây; trạng thái thời gian chạy của bộ ngắt mạch nằm trên trang Tình trạng.", + "emailVisibilityHint": "Các email tài khoản ở đây tuân theo tùy chọn bật/tắt quyền riêng tư toàn cục.", + "emailVisibilityTooltip": "Sử dụng biểu tượng con mắt để hiển thị hoặc ẩn email tài khoản trên toàn bộ màn hình combo, nhà cung cấp và hạn mức.", + "manualModel": "Mô hình thủ công", + "manualModelInvalid": "Nhập mô hình theo dạng nhà cung cấp/mô hình.", + "manualModelUnknownProvider": "Tiền tố nhà cung cấp không xác định.", + "builderDynamicAccountShort": "Tài khoản động", + "builderNeedValidName": "Xác định tên combo hợp lệ trước khi tiếp tục.", + "statusOverview": "Tổng quan trạng thái", + "normalOperation": "Hoạt động bình thường", + "allProvidersHealthy": "Các nhà cung cấp đang báo cáo điều kiện định tuyến bình thường.", + "incidentMode": "Chế độ sự cố", + "highCircuitBreakerRate": "Phát hiện tỷ lệ kích hoạt bộ ngắt mạch cao.", + "activeModePack": "Gói chế độ hoạt động", + "modePackUpdated": "Gói chế độ đã được cập nhật thành {pack}.", + "modePackHint": "Chuyển đổi các cấu hình sẵn để điều chỉnh thiên hướng của công cụ định tuyến mà không cần tạo lại combo.", + "providerScores": "Điểm số nhà cung cấp", + "allProvidersEvaluated": "Chưa cấu hình nhóm ứng viên. Tất cả nhà cung cấp đang hoạt động sẽ được đánh giá trong thời gian chạy.", + "excludedProviders": "Nhà cung cấp bị loại trừ", + "excludedProvidersHint": "Các nhà cung cấp có trạng thái ngắt mạch là MỞ sẽ tạm thời bị loại trừ khỏi định tuyến.", + "noExcludedProviders": "Hiện tại không có nhà cung cấp nào bị loại trừ.", + "cooldownMinutes": "Thời gian chờ: {minutes}m", + "builderIntelligentTitle": "Cấu hình định tuyến thông minh", + "builderIntelligentDesc": "Cấu hình bộ máy chấm điểm đa yếu tố cho combo định tuyến tự động này.", + "candidatePoolLabel": "Nhóm ứng viên", + "candidatePoolHint": "Chọn các nhà cung cấp mà bộ máy này sẽ đánh giá. Để trống để sử dụng tất cả các nhà cung cấp đang hoạt động.", + "candidatePoolEmpty": "Chưa có nhà cung cấp đang hoạt động nào khả dụng.", + "candidatePoolAllProviders": "Tất cả nhà cung cấp", + "modePackLabel": "Gói chế độ", + "routerStrategyLabel": "Chiến lược định tuyến", + "strategyRules": "Quy tắc (Chấm điểm 6 yếu tố)", + "explorationRateLabel": "Tỷ lệ khám phá", + "explorationRateHint": "{percent}% yêu cầu có thể dùng để khám phá các nhà cung cấp không tối ưu.", + "budgetCapLabel": "Hạn mức ngân sách (USD / yêu cầu)", + "budgetCapPlaceholder": "Không giới hạn", + "advancedWeightsTitle": "Nâng cao: Trọng số chấm điểm", + "weightQuota": "Hạn mức", + "weightHealth": "Trạng thái hoạt động", + "weightCostInv": "Chi phí", + "weightLatencyInv": "Độ trễ", + "weightTaskFit": "Độ phù hợp tác vụ", + "weightStability": "Độ ổn định", + "weightTierPriority": "Phân hạng", + "reviewIntelligentTitle": "Cấu hình định tuyến thông minh", "strategyRecommendations": { "priority": { - "title": "Fail-safe baseline", - "description": "Use one primary model and keep fallback chain short and reliable.", - "tip1": "Put your most reliable model first.", - "tip2": "Keep 1-2 backup models with similar quality.", - "tip3": "Use safe retries to absorb transient provider failures." + "title": "Phương án cơ sở an toàn khi có sự cố", + "description": "Sử dụng một mô hình chính và giữ chuỗi dự phòng ngắn và đáng tin cậy.", + "tip1": "Đặt mô hình đáng tin cậy nhất của bạn lên đầu.", + "tip2": "Duy trì 1–2 mô hình dự phòng có chất lượng tương đương.", + "tip3": "Sử dụng thử lại an toàn để giảm thiểu các lỗi tạm thời của nhà cung cấp." }, "weighted": { - "title": "Controlled traffic split", - "description": "Great for canary rollouts and gradual migration between models.", - "tip1": "Start with conservative split like 90/10.", - "tip2": "Keep the total at 100% and auto-balance after changes.", - "tip3": "Monitor success and latency before increasing canary weight." + "title": "Chia tách lưu lượng có kiểm soát", + "description": "Rất phù hợp cho việc triển khai canary và chuyển đổi dần dần giữa các mô hình.", + "tip1": "Bắt đầu với tỷ lệ phân chia thận trọng như 90/10.", + "tip2": "Luôn giữ tổng tỷ lệ ở mức 100% và tự động cân bằng sau khi thay đổi.", + "tip3": "Theo dõi tỷ lệ thành công và độ trễ trước khi tăng trọng số canary." }, "round-robin": { - "title": "Predictable load sharing", - "description": "Best when models are equivalent and you need smooth distribution.", - "tip1": "Use at least 2 models.", - "tip2": "Set concurrency limits to avoid burst overload.", - "tip3": "Use queue timeout to fail fast under saturation." + "title": "Chia sẻ tải có thể dự đoán", + "description": "Phù hợp nhất khi các mô hình tương đương và bạn cần phân phối đồng đều.", + "tip1": "Sử dụng ít nhất 2 mô hình.", + "tip2": "Thiết lập giới hạn số yêu cầu đồng thời để tránh quá tải đột biến.", + "tip3": "Sử dụng thời gian chờ của hàng đợi để báo lỗi nhanh khi hệ thống bão hòa." }, "random": { - "title": "Quick spread with low setup", - "description": "Use when you need simple distribution without strict guarantees.", - "tip1": "Use models with similar latency profiles.", - "tip2": "Keep retries enabled to absorb random misses.", - "tip3": "Prefer this for experimentation, not strict SLAs." + "title": "Phân bổ nhanh chóng với thiết lập tối giản", + "description": "Sử dụng khi bạn cần phân phối đơn giản mà không cần các đảm bảo nghiêm ngặt.", + "tip1": "Sử dụng các mô hình có đặc điểm độ trễ tương tự.", + "tip2": "Bật chế độ thử lại để giảm thiểu các lần không thành công ngẫu nhiên.", + "tip3": "Ưu tiên lựa chọn này cho việc thử nghiệm, không dùng cho các cam kết SLA nghiêm ngặt." }, "least-used": { - "title": "Adaptive balancing", - "description": "Routes to less-used models to reduce hotspots over time.", - "tip1": "Works better under continuous traffic.", - "tip2": "Combine with health checks for safer balancing.", - "tip3": "Track per-model usage to validate distribution gains." + "title": "Cân bằng thích ứng", + "description": "Định tuyến đến các mô hình ít được sử dụng hơn để giảm các điểm nóng theo thời gian.", + "tip1": "Hoạt động tốt hơn dưới lưu lượng truy cập liên tục.", + "tip2": "Kết hợp với kiểm tra trạng thái để cân bằng an toàn hơn.", + "tip3": "Theo dõi mức sử dụng của từng mô hình để xác thực hiệu quả phân phối." }, "cost-optimized": { - "title": "Budget-first routing", - "description": "Routes to lower-cost models when pricing metadata is available.", - "tip1": "Ensure pricing coverage for all selected models.", - "tip2": "Keep a quality fallback for hard prompts.", - "tip3": "Use for batch/background jobs where cost is the main KPI." + "title": "Định tuyến ưu tiên ngân sách", + "description": "Định tuyến đến các mô hình có chi phí thấp hơn khi có sẵn siêu dữ liệu định giá.", + "tip1": "Đảm bảo có thông tin định giá cho tất cả các mô hình đã chọn.", + "tip2": "Duy trì một mô hình dự phòng chất lượng cho các prompt khó.", + "tip3": "Sử dụng cho các tác vụ hàng loạt hoặc chạy ngầm khi chi phí là KPI chính." }, "reset-aware": { - "title": "Đặt lại vòng quay tài khoản nhận biết", - "description": "Cân bằng hạn ngạch nhà cung cấp còn lại với thời gian đặt lại.", - "tip1": "Sử dụng các bước tài khoản hoặc định tuyến thẻ tài khoản rõ ràng cho các nhà cung cấp có hạn mức đo từ xa.", - "tip2": "Điều chỉnh buổi tập so với mức tạ hàng tuần khi tình trạng kiệt sức trong thời gian ngắn có nhiều rủi ro hơn.", - "tip3": "Giữ dây buộc nhỏ để các tài khoản tương đương vẫn xoay vòng một cách công bằng." + "title": "Xoay vòng tài khoản theo thời điểm đặt lại", + "description": "Cân bằng hạn ngạch còn lại của nhà cung cấp với thời điểm đặt lại.", + "tip1": "Sử dụng các bước tài khoản rõ ràng hoặc định tuyến theo thẻ tài khoản cho các nhà cung cấp có dữ liệu theo dõi hạn ngạch.", + "tip2": "Điều chỉnh trọng số theo phiên và theo tuần khi rủi ro cạn kiệt trong ngắn hạn cao hơn.", + "tip3": "Giữ khoảng chênh lệch nhỏ để các tài khoản tương đương vẫn được xoay vòng công bằng." }, "strict-random": { - "title": "Shuffle deck distribution", - "description": "Each model is used exactly once per cycle before reshuffling.", - "tip1": "Use at least 2 models for meaningful distribution.", - "tip2": "Works best with equivalent-performance models.", - "tip3": "Ideal for load balancing across multiple API accounts." + "title": "Phân phối theo bộ bài xáo trộn", + "description": "Mỗi mô hình được sử dụng chính xác một lần trong mỗi chu kỳ trước khi xáo trộn lại.", + "tip1": "Sử dụng ít nhất 2 mô hình để việc phân phối có ý nghĩa.", + "tip2": "Hoạt động tốt nhất với các mô hình có hiệu năng tương đương.", + "tip3": "Lý tưởng để cân bằng tải trên nhiều tài khoản API." }, "fill-first": { - "description": "Hạn ngạch của nhà cung cấp xả thải tuần tự trước khi quay trở lại.", - "tip1": "Sử dụng để định tuyến dựa trên hạn ngạch với chuỗi dự phòng rõ ràng.", - "tip2": "Đặt hạn ngạch chính xác để tránh dự phòng sớm.", - "tip3": "Hoạt động tốt nhất với các nhà cung cấp cung cấp cấp độ miễn phí hoặc nhóm tín dụng.", + "description": "Sử dụng hết hạn ngạch của nhà cung cấp theo thứ tự trước khi chuyển sang phương án dự phòng.", + "tip1": "Sử dụng để định tuyến dựa trên hạn ngạch với các chuỗi dự phòng rõ ràng.", + "tip2": "Thiết lập hạn ngạch chính xác để tránh chuyển sang phương án dự phòng quá sớm.", + "tip3": "Hoạt động tốt nhất với các nhà cung cấp cung cấp gói dịch vụ miễn phí hoặc các gói tín dụng.", "title": "Cạn kiệt hạn ngạch" }, "auto": { - "description": "Lộ trình dựa trên việc tính điểm theo thời gian thực về chi phí, độ trễ, chất lượng và tình trạng.", - "tip1": "Để động cơ tự động cân bằng nhiều yếu tố.", - "tip2": "Giám sát những yếu tố thúc đẩy quyết định định tuyến trong nhật ký.", - "tip3": "Sử dụng cho khối lượng công việc phức tạp mà không có yếu tố nào chiếm ưu thế.", + "description": "Định tuyến dựa trên điểm số theo thời gian thực về chi phí, độ trễ, chất lượng và tình trạng hoạt động.", + "tip1": "Để hệ thống tự động cân bằng nhiều yếu tố.", + "tip2": "Theo dõi các yếu tố quyết định việc định tuyến trong nhật ký.", + "tip3": "Sử dụng cho các khối lượng công việc phức tạp mà không có yếu tố đơn lẻ nào chiếm ưu thế.", "title": "Tối ưu hóa đa yếu tố" }, "lkgp": { - "description": "Lộ trình dựa trên hiệu suất lịch sử và mô hình thành công.", - "tip1": "Yêu cầu có đủ lịch sử yêu cầu để dự đoán chính xác.", - "tip2": "Tốt cho khối lượng công việc có mô hình hiệu suất mô hình nhất quán.", + "description": "Định tuyến dựa trên hiệu suất trong quá khứ và các mẫu hình thành công.", + "tip1": "Yêu cầu có đủ lịch sử yêu cầu để đưa ra dự đoán chính xác.", + "tip2": "Phù hợp cho các khối lượng công việc có mẫu hình hiệu suất nhất quán của mô hình.", "tip3": "Theo dõi độ chính xác của dự đoán và điều chỉnh trọng số khi cần thiết.", "title": "Định tuyến dựa trên lịch sử" }, "context-optimized": { - "description": "Tối ưu hóa định tuyến dựa trên việc sử dụng cửa sổ ngữ cảnh và hiệu quả của mã thông báo.", + "description": "Tối ưu hóa định tuyến dựa trên mức sử dụng cửa sổ ngữ cảnh và hiệu quả sử dụng token.", "tip1": "Định tuyến các cuộc hội thoại dài đến các mô hình có cửa sổ ngữ cảnh lớn hơn.", - "tip2": "Giám sát việc sử dụng ngữ cảnh để tránh lãng phí mã thông báo.", - "tip3": "Phù hợp nhất cho AI đàm thoại yêu cầu lưu giữ ngữ cảnh rộng rãi.", - "title": "Tối ưu hóa bối cảnh" + "tip2": "Theo dõi mức sử dụng ngữ cảnh để tránh lãng phí token.", + "tip3": "Phù hợp nhất cho AI đàm thoại yêu cầu duy trì ngữ cảnh lâu dài.", + "title": "Tối ưu hóa ngữ cảnh" }, "context-relay": { - "description": "Tốt nhất khi dự kiến xoay vòng tài khoản và tài khoản tiếp theo phải kế thừa bản tóm tắt nhiệm vụ được đơn giản hóa.", - "tip1": "Sử dụng với các nhà cung cấp tài khoản luân phiên cho cùng một nhóm mô hình.", - "tip2": "Đặt ngưỡng chuyển giao dưới mức giới hạn hạn ngạch cứng cho thời gian tạo tóm tắt.", - "tip3": "Chỉ đặt mô hình tóm tắt chuyên dụng nếu mô hình chính quá đắt hoặc không ổn định.", - "title": "Ưu tiên liên tục của phiên" + "description": "Phù hợp nhất khi dự kiến có sự luân chuyển tài khoản và tài khoản tiếp theo cần kế thừa một bản tóm tắt công việc được đơn giản hóa.", + "tip1": "Sử dụng với các nhà cung cấp thực hiện luân chuyển tài khoản cho cùng một dòng mô hình.", + "tip2": "Đặt ngưỡng chuyển giao thấp hơn giới hạn hạn ngạch cứng để dành thời gian tạo bản tóm tắt.", + "tip3": "Chỉ thiết lập một mô hình tóm tắt chuyên dụng nếu mô hình chính quá đắt hoặc không ổn định.", + "title": "Ưu tiên tính liên tục của phiên" }, "p2c": { - "description": "Định tuyến đến nhà cung cấp có lưu lượng hiện tại thấp nhất dựa trên số liệu thời gian thực.", - "tip1": "Theo dõi số liệu sức khỏe của nhà cung cấp để đánh giá tải chính xác.", - "tip2": "Hoạt động tốt nhất với nhóm nhà cung cấp đồng nhất.", - "tip3": "Điều chỉnh độ nhạy để tránh dao động khi lưu lượng truy cập tăng đột biến.", - "title": "Sức mạnh của hai sự lựa chọn" + "description": "Định tuyến đến nhà cung cấp có tải hiện tại thấp nhất dựa trên các số liệu thời gian thực.", + "tip1": "Theo dõi các số liệu tình trạng hoạt động của nhà cung cấp để đánh giá tải chính xác.", + "tip2": "Hoạt động tốt nhất với các nhóm nhà cung cấp đồng nhất.", + "tip3": "Điều chỉnh độ nhạy để tránh hiện tượng dao động khi lưu lượng truy cập tăng đột biến.", + "title": "Sức mạnh của hai lựa chọn" } }, - "templateFreeStack": "Free Stack ($0)", - "templateFreeStackDesc": "Round-robin across all free providers: Kiro (Claude), Qoder (5 models), Qwen (4 models). Zero cost, never stops coding.", - "auto": "Auto Combo", - "autoDesc": "Self-healing smart routing pool (Performance optimized)", - "lkgp": "LKGP Mode", - "lkgpDesc": "Last Known Good Provider (Predictable resilience)", - "wizardGuideTitle": "Getting Started with Combos", - "wizardGuideDesc": "Create model combos to route AI traffic intelligently", - "wizardGuideHint": "or click + Create Combo above", - "createFirstCombo": "Create Your First Combo", - "wizardStep1Title": "Name Your Combo", - "wizardStep1Desc": "Give your combo a unique name to identify it in routing rules", - "wizardStep2Title": "Add Models", - "wizardStep2Desc": "Select AI models and arrange their fallback priority order", - "wizardStep3Title": "Choose Strategy", - "wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available", - "wizardStep4Title": "Review & Save", - "wizardStep4Desc": "Review your configuration and activate the combo", - "emailVisibilityStateOn": "On", - "emailVisibilityStateOff": "Off", - "reorderHandle": "Drag to reorder", - "failedReorder": "Failed to reorder models", - "builderFlowTitle": "Combo Builder Flow", + "templateFreeStack": "Bộ miễn phí ($0)", + "templateFreeStackDesc": "Định tuyến xoay vòng qua tất cả nhà cung cấp miễn phí: Kiro (Claude), Qoder (5 mô hình), Qwen (4 mô hình). Không tốn chi phí, không bao giờ ngừng lập trình.", + "auto": "Tự động thông minh", + "autoDesc": "Nhóm định tuyến thông minh tự phục hồi với tính điểm đa yếu tố", + "lkgp": "Chế độ LKGP", + "lkgpDesc": "Ưu tiên nhà cung cấp gần nhất đã hoàn thành yêu cầu thành công", + "wizardGuideTitle": "Bắt đầu với Combo", + "wizardGuideDesc": "Tạo các combo mô hình để định tuyến lưu lượng AI một cách thông minh", + "wizardGuideHint": "hoặc nhấp vào + Tạo Combo ở trên", + "createFirstCombo": "Tạo Combo đầu tiên của bạn", + "wizardStep1Title": "Đặt tên cho Combo của bạn", + "wizardStep1Desc": "Đặt cho combo của bạn một tên duy nhất để nhận diện trong các quy tắc định tuyến", + "wizardStep2Title": "Thêm mô hình", + "wizardStep2Desc": "Chọn các mô hình AI và sắp xếp thứ tự ưu tiên dự phòng của chúng", + "wizardStep3Title": "Chọn chiến lược", + "wizardStep3Desc": "Chọn cách phân phối các yêu cầu giữa các mô hình của bạn - hiện có 14 chiến lược", + "wizardStep4Title": "Xem lại & Lưu", + "wizardStep4Desc": "Xem lại cấu hình của bạn và kích hoạt combo", + "emailVisibilityStateOn": "Bật", + "emailVisibilityStateOff": "Tắt", + "reorderHandle": "Kéo để sắp xếp lại", + "failedReorder": "Không thể sắp xếp lại các mô hình", + "builderFlowTitle": "Luồng xây dựng Combo", "builderStage": { "basics": { - "label": "Basics", - "description": "Name and starting template" + "label": "Cơ bản", + "description": "Tên và mẫu ban đầu" }, "steps": { - "label": "Steps", - "description": "Provider, model, and account selection" + "label": "Các bước", + "description": "Lựa chọn nhà cung cấp, mô hình và tài khoản" }, "strategy": { - "label": "Strategy", - "description": "Routing behavior and advanced settings" + "label": "Chiến lược", + "description": "Hành vi định tuyến và cài đặt nâng cao" }, "intelligent": { - "label": "Smart Routing", - "description": "Auto-routing candidate pool, presets, and scoring" + "label": "Định tuyến thông minh", + "description": "Nhóm ứng viên để tự động định tuyến, thiết lập sẵn và tính điểm" }, "review": { - "label": "Review", - "description": "Final validation before saving" + "label": "Xem lại", + "description": "Xác thực cuối cùng trước khi lưu" } }, - "builderStageVisited": "Stage completed", - "builderStageCurrent": "Current stage", - "builderStagePending": "Pending", - "builderStageLocked": "Locked — complete previous stage first", - "builderTitle": "Build a Combo", - "builderBrowseCatalog": "Browse catalog", - "builderProvider": "Provider", - "builderLoadingProviders": "Loading providers...", - "builderSelectProvider": "Select provider", - "builderModel": "Model", - "builderSelectModel": "Select model", - "builderProviderFirst": "Pick provider first", - "builderAccount": "Account", - "builderPreview": "Preview", - "builderAddStep": "Add step", - "builderDuplicateExact": "Bước nhà cung cấp/mô hình/tài khoản chính xác này đã có trong combo.", - "builderComboRef": "Combo Ref", - "builderAddComboRef": "Add combo reference", - "builderComboRefStep": "Add combo reference", - "builderPinnedAccount": "Pinned Account", - "builderLegacyEntry": "Legacy entry", - "reviewName": "Name", - "reviewStrategy": "Strategy", - "reviewSteps": "Steps", - "reviewAccounts": "Accounts", - "reviewProviders": "Providers", - "reviewComboRefs": "Combo References", - "reviewAdvanced": "Advanced Settings", - "reviewAgentFlags": "Agent Flags", - "reviewSequence": "Model Sequence", - "reviewNoSteps": "No steps configured", - "builderStagesDescription": "Hoàn thành từng giai đoạn để xác định tổ hợp, xây dựng các bước, chọn chiến lược định tuyến và xem xét kết quả.", - "builderStepsDescription": "Xây dựng từng bước kết hợp theo thứ tự: nhà cung cấp, mô hình, sau đó là tài khoản. Điều này cho phép sử dụng lại cùng một nhà cung cấp và mô hình trên các tài khoản khác nhau.", + "builderStageVisited": "Giai đoạn đã hoàn thành", + "builderStageCurrent": "Giai đoạn hiện tại", + "builderStagePending": "Đang chờ xử lý", + "builderStageLocked": "Đã khóa — hãy hoàn thành giai đoạn trước đó", + "builderTitle": "Xây dựng một Combo", + "builderBrowseCatalog": "Duyệt danh mục", + "builderProvider": "Nhà cung cấp", + "builderLoadingProviders": "Đang tải các nhà cung cấp...", + "builderSelectProvider": "Chọn nhà cung cấp", + "builderModel": "Mô hình", + "builderSelectModel": "Chọn mô hình", + "builderProviderFirst": "Chọn nhà cung cấp trước", + "builderAccount": "Tài khoản", + "builderPreview": "Xem trước", + "builderAddStep": "Thêm bước", + "builderDuplicateExact": "Bước gồm đúng nhà cung cấp/mô hình/tài khoản này đã có trong combo.", + "builderComboRef": "Tham chiếu Combo", + "builderAddComboRef": "Thêm tham chiếu combo", + "builderComboRefStep": "Thêm tham chiếu combo", + "builderPinnedAccount": "Tài khoản được ghim", + "builderLegacyEntry": "Mục nhập cũ", + "reviewName": "Tên", + "reviewStrategy": "Chiến lược", + "reviewSteps": "Các bước", + "reviewAccounts": "Tài khoản", + "reviewProviders": "Nhà cung cấp", + "reviewComboRefs": "Tham chiếu Combo", + "reviewAdvanced": "Cài đặt nâng cao", + "reviewAgentFlags": "Cờ Agent", + "reviewSequence": "Trình tự mô hình", + "reviewNoSteps": "Chưa có bước nào được cấu hình", + "builderStagesDescription": "Hoàn thành từng giai đoạn theo thứ tự để thiết lập combo, xây dựng các bước, chọn chiến lược định tuyến và xem lại kết quả.", + "builderStepsDescription": "Xây dựng từng bước combo theo thứ tự: nhà cung cấp, mô hình, sau đó là tài khoản. Điều này cho phép sử dụng lại cùng một nhà cung cấp và mô hình trên các tài khoản khác nhau.", "selectProvider": "Chọn nhà cung cấp", - "selectProviderPlaceholder": "Chọn nhà cung cấp", - "selectModel": "Chọn mẫu", + "selectProviderPlaceholder": "Chọn một nhà cung cấp", + "selectModel": "Chọn mô hình", "selectModelPlaceholder": "Chọn nhà cung cấp trước", "selectAccount": "Chọn tài khoản", - "selectComboToReference": "Chọn combo để tham khảo", - "comboReference": "Tham khảo kết hợp", - "addComboReference": "Thêm tài liệu tham khảo kết hợp", + "selectComboToReference": "Chọn combo để tham chiếu", + "comboReference": "Tham chiếu combo", + "addComboReference": "Thêm tham chiếu combo", "addStepBeforeContinue": "Vui lòng thêm ít nhất một bước trước khi chuyển sang giai đoạn tiếp theo.", "previewNextStep": "Xem trước bước tiếp theo", - "autoSelectAccount": "Tự động chọn tài khoản khi chạy", + "autoSelectAccount": "Tự động chọn tài khoản trong thời gian chạy", "modePackBalanced": "Cân bằng", "modePackBudget": "Ngân sách", "modePackPerformance": "Hiệu suất", - "modePackCustom": "tùy chỉnh", - "browseLegacyCatalog": "Duyệt qua danh mục kết hợp kế thừa", - "agentFeaturesTitle": "Tính năng đại lý", - "agentFeaturesDescription": "Kích hoạt các tính năng nâng cao cho các đại lý sử dụng combo này", + "modePackCustom": "Tùy chỉnh", + "browseLegacyCatalog": "Duyệt qua danh mục combo cũ", + "agentFeaturesTitle": "Tính năng tác nhân", + "agentFeaturesDescription": "Kích hoạt các tính năng nâng cao cho các tác nhân sử dụng combo này", "agentFeaturesSystemMessageOverride": "Ghi đè thông báo hệ thống", - "agentFeaturesSystemMessagePlaceholder": "Bạn là trợ lý chuyên nghiệp...", - "agentFeaturesSystemMessageHint": "Ghi đè thông báo hệ thống cho đại lý", - "agentFeaturesToolFilterRegex": "/mẫu biểu thức chính quy/", - "agentFeaturesToolFilterHint": "Công cụ lọc biểu thức chính quy cho đại lý", - "agentFeaturesContextCacheHint": "Bật bộ nhớ đệm trong ngữ cảnh cho các công cụ tác nhân", - "agentFeaturesContextCacheProtection": "Bảo vệ bộ đệm khỏi đột biến công cụ tác nhân", + "agentFeaturesSystemMessagePlaceholder": "Bạn là một trợ lý chuyên nghiệp...", + "agentFeaturesSystemMessageHint": "Ghi đè thông báo hệ thống cho tác nhân", + "agentFeaturesToolFilterRegex": "/regex-pattern/", + "agentFeaturesToolFilterHint": "Regex lọc công cụ cho tác nhân", + "agentFeaturesContextCacheHint": "Bật cache trong ngữ cảnh cho các công cụ của tác nhân", + "agentFeaturesContextCacheProtection": "Bảo vệ cache khỏi các thay đổi do công cụ của tác nhân gây ra", "agentFeaturesContextLength": "Độ dài ngữ cảnh", "agentFeaturesContextLengthPlaceholder": "ví dụ: 128000", - "agentFeaturesContextLengthHint": "Xác định cửa sổ ngữ cảnh cho tổ hợp này trong /v1/models.", + "agentFeaturesContextLengthHint": "Xác định cửa sổ ngữ cảnh cho combo này trong /v1/models.", "agentFeaturesContextLengthErrorInteger": "Độ dài ngữ cảnh phải là số nguyên hợp lệ", "agentFeaturesContextLengthErrorRange": "Độ dài ngữ cảnh phải nằm trong khoảng từ 1000 đến 2000000", "compressionOverride": "Ghi đè nén", - "modePack": "Gói chế độ" + "modePack": "Gói chế độ", + "comboDescription": "Description", + "comboDescriptionPlaceholder": "Optional note describing this combo", + "fusion": "Fusion", + "fusionDesc": "Fans the prompt to every panel model in parallel, then a judge model synthesizes one final answer", + "fusionJudgeModel": "Judge model", + "fusionJudgeModelHelp": "Model that synthesizes the panel answers into one final response. Leave empty to use the first panel model.", + "fusionMinPanel": "Min panel", + "fusionMinPanelHelp": "Successful panel answers required before stragglers get a grace window (default 2).", + "fusionStragglerGraceMs": "Straggler grace (ms)", + "fusionStragglerGraceMsHelp": "How long to wait for slow panel models once quorum is reached (default 8000).", + "fusionPanelHardTimeoutMs": "Panel hard timeout (ms)", + "fusionPanelHardTimeoutMsHelp": "Absolute cap so one hung model can't stall the whole panel (default 90000).", + "responseValidationTitle": "Response validation", + "responseValidationHelp": "Fail over to the next target when a 200 OK body fails these checks (assistant content).", + "responseValidationForbidden": "Forbidden substrings (one per line)", + "responseValidationRequired": "Required substrings (one per line)", + "responseValidationMinLength": "Minimum content length (chars)", + "responseValidationJsonPaths": "JSON-path checks", + "responseValidationAddCheck": "+ Add check", + "disableSessionStickiness": "Disable session stickiness", + "sessionStickinessEnabled": "Stickiness on", + "sessionStickinessDisabled": "Stickiness off" }, "costs": { "title": "Chi phí", @@ -2719,44 +2889,44 @@ "overview": "Tổng quan", "budget": "Ngân sách", "totalCost": "Tổng chi phí", - "breakdown": "Phân tích chi phí", + "breakdown": "Chi tiết chi phí", "noData": "Không có dữ liệu chi phí", - "byModel": "Theo mẫu", + "byModel": "Theo mô hình", "byProvider": "Theo nhà cung cấp", "range7d": "7 ngày", "range30d": "30 ngày", "range90d": "90 ngày", - "range180d": "180 Days", - "range365d": "365 Days", - "rangeAll": "mọi lúc", - "spend30d": "Spend30D", - "activeModels": "Active Models", - "selectedWindow": "Selected Window", - "activeProviders": "Active Providers", - "overviewTitle": "Overview Title", - "spend7d": "Spend7D", - "avgCostPerRequest": "Avg Cost Per Request", - "noCostDataDescription": "No Cost Data Description", - "spendToday": "Spend Today", - "overviewLoadFailed": "Overview Load Failed", - "overviewDescription": "Overview Description", - "providerShare": "Provider Share", - "topProviders": "Top Providers", - "costTrend": "Cost Trend", - "noCostDataTitle": "No Cost Data Title", - "topModels": "Top Models", - "requestsInWindow": "Requests In Window", - "tokenUsage": "Sử dụng mã thông báo", + "range180d": "180 ngày", + "range365d": "365 ngày", + "rangeAll": "Toàn bộ thời gian", + "spend30d": "Chi tiêu 30 ngày", + "activeModels": "Mô hình đang hoạt động", + "selectedWindow": "Khoảng thời gian đã chọn", + "activeProviders": "Nhà cung cấp đang hoạt động", + "overviewTitle": "Tổng quan chi phí", + "spend7d": "Chi tiêu 7 ngày", + "avgCostPerRequest": "Chi phí trung bình / yêu cầu", + "noCostDataDescription": "Bắt đầu thực hiện các yêu cầu để xem dữ liệu chi phí xuất hiện tại đây. Chi phí được theo dõi tự động cho tất cả các nhà cung cấp.", + "spendToday": "Chi tiêu hôm nay", + "overviewLoadFailed": "Không thể tải tổng quan chi phí", + "overviewDescription": "Phân tích chi tiêu theo thời gian thực trên tất cả các nhà cung cấp và mô hình đã kết nối", + "providerShare": "Tỷ trọng theo nhà cung cấp", + "topProviders": "Nhà cung cấp hàng đầu", + "costTrend": "Xu hướng chi phí", + "noCostDataTitle": "Chưa có dữ liệu chi phí", + "topModels": "Mô hình hàng đầu", + "requestsInWindow": "Yêu cầu trong khoảng thời gian", + "tokenUsage": "Mức sử dụng token", "totalTokens": "Tổng số token", - "inputTokens": "Mã thông báo đầu vào", - "outputTokens": "Mã thông báo đầu ra", + "inputTokens": "Token đầu vào", + "outputTokens": "Token đầu ra", "inputOutputRatio": "Tỷ lệ đầu vào/đầu ra", - "tokens": "mã thông báo", + "tokens": "token", "routingEfficiency": "Hiệu quả định tuyến", "fallbackCount": "Yêu cầu dự phòng", "fallbackRate": "Tỷ lệ dự phòng", - "modelCoverage": "Phạm vi bảo hiểm của mô hình", - "modelCoverageDesc": "% yêu cầu có mô hình rõ ràng", + "modelCoverage": "Mức độ bao phủ mô hình", + "modelCoverageDesc": "% yêu cầu có mô hình được chỉ định rõ ràng", "outOfRequests": "trong số {total} yêu cầu", "costByApiKey": "Chi phí theo khóa API", "costByAccount": "Chi phí theo tài khoản", @@ -2764,21 +2934,21 @@ "account": "Tài khoản", "requests": "Yêu cầu", "cost": "Chi phí", - "dayStreak": "vệt ngày", + "dayStreak": "chuỗi ngày liên tiếp", "weeklyUsagePattern": "Mẫu sử dụng hàng tuần", "activityHeatmap": "Hoạt động (365 ngày)", "less": "Ít hơn", - "more": "Thêm", + "more": "Nhiều hơn", "monthlyForecast": "Dự báo hàng tháng", "forecastBasis": "Dựa trên {days} ngày qua", - "avgDailyCost": "Trung bình chi phí hàng ngày", - "daysRemaining": "Còn {days} ngày", - "periodComparison": "So sánh thời gian", - "previousPeriod": "Hiệp trước", + "avgDailyCost": "Chi phí trung bình hàng ngày", + "daysRemaining": "Còn lại {days} ngày", + "periodComparison": "So sánh thời kỳ", + "previousPeriod": "Nửa trước", "currentPeriod": "Nửa hiện tại", "exportCSV": "Xuất dưới dạng CSV", "exportJSON": "Xuất dưới dạng JSON", - "legacyFreeLabel": "__MISSING__:Legacy / Free", + "legacyFreeLabel": "Cũ / Miễn phí", "costExplorerTitle": "Trình khám phá chi phí", "costExplorerDescription": "Khám phá chi tiêu theo nhà cung cấp, mô hình, khóa API, tài khoản hoặc cấp dịch vụ.", "groupProvider": "Nhà cung cấp", @@ -2786,32 +2956,32 @@ "groupApiKey": "Khóa API", "groupAccount": "Tài khoản", "groupServiceTier": "Cấp dịch vụ", - "serviceTierFast": "__MISSING__:Fast", - "serviceTierFlex": "__MISSING__:Flex", - "serviceTierStandard": "__MISSING__:Standard", - "serviceTierBreakdownTitle": "__MISSING__:Service Tier", - "serviceTierBreakdownSubtitle": "__MISSING__:Fast / Flex / Standard split", - "serviceTierUsageSaved": "__MISSING__:usage saved", - "serviceTierCostSaved": "__MISSING__:saved", - "serviceTierCostShareSuffix": "__MISSING__:of cost", - "dimension": "Chiều", + "serviceTierFast": "Nhanh", + "serviceTierFlex": "Linh hoạt", + "serviceTierStandard": "Tiêu chuẩn", + "serviceTierBreakdownTitle": "Cấp dịch vụ", + "serviceTierBreakdownSubtitle": "Phân chia Nhanh / Linh hoạt / Tiêu chuẩn", + "serviceTierUsageSaved": "mức sử dụng đã tiết kiệm", + "serviceTierCostSaved": "đã tiết kiệm", + "serviceTierCostShareSuffix": "trong tổng chi phí", + "dimension": "Khía cạnh", "share": "Tỷ trọng", "legacyOrFree": "Cũ / miễn phí", "filterRows": "Lọc hàng…", - "filterCostExplorerRows": "Lọc hàng của trình khám phá chi phí", + "filterCostExplorerRows": "Lọc các hàng trong Trình khám phá chi phí", "noMatchingCostRows": "Không có hàng chi phí phù hợp", "noMatchingCostRowsDescription": "Điều chỉnh văn bản tìm kiếm, cách nhóm hoặc khoảng thời gian đã chọn.", "showingCostRows": "Đang hiển thị {shown} trong tổng số {total} hàng phù hợp.", - "showingTopCostRows": "Đang hiển thị {shown} trong tổng số {total} hàng phù hợp (top 50)." + "showingTopCostRows": "Đang hiển thị {shown} trong tổng số {total} hàng phù hợp (50 hàng đầu)." }, "endpoint": { - "title": "Điểm cuối API", - "available": "Điểm cuối có sẵn", + "title": "Endpoint API", + "available": "Các endpoint có sẵn", "cloudProxy": "Proxy đám mây", "disableConfirm": "Bạn có chắc chắn muốn tắt proxy đám mây không?", "baseUrl": "URL cơ sở", "apiKeyLabel": "Khóa API", - "registeredKeys": "Khóa đã đăng ký", + "registeredKeys": "Các khóa đã đăng ký", "chatCompletions": "Hoàn thành cuộc trò chuyện", "responses": "Phản hồi", "listModels": "Danh sách mô hình", @@ -2820,509 +2990,664 @@ "machineId": "ID máy: {id}...", "disableCloud": "Tắt đám mây", "enableCloud": "Kích hoạt đám mây", - "modelsAcrossEndpoints": "{models} mô hình trên {endpoints} điểm cuối", - "loadingModels": "Loading available models...", - "chatDesc": "Trò chuyện trực tuyến và không phát trực tuyến với tất cả các nhà cung cấp", + "modelsAcrossEndpoints": "{models} mô hình trên {endpoints} endpoint", + "loadingModels": "Đang tải các mô hình có sẵn...", + "chatDesc": "Trò chuyện có và không có phát trực tuyến với tất cả nhà cung cấp", "embeddings": "Nhúng", - "embeddingsDesc": "Nhúng văn bản cho đường dẫn tìm kiếm & RAG", + "embeddingsDesc": "Nhúng văn bản cho quy trình tìm kiếm và RAG", "imageGeneration": "Tạo hình ảnh", - "imageDesc": "Tạo hình ảnh từ lời nhắc văn bản", + "imageDesc": "Tạo hình ảnh từ các prompt văn bản", "rerank": "Xếp hạng lại", "rerankDesc": "Sắp xếp lại tài liệu theo mức độ liên quan đến truy vấn", "audioTranscription": "Phiên âm âm thanh", - "audioTranscriptionDesc": "Phiên âm tập tin âm thanh thành văn bản (Whisper)", + "audioTranscriptionDesc": "Phiên âm các tệp âm thanh thành văn bản (Whisper)", "textToSpeech": "Chuyển văn bản thành giọng nói", "textToSpeechDesc": "Chuyển đổi văn bản thành giọng nói tự nhiên", - "musicGeneration": "Music Generation", - "musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)", + "musicGeneration": "Tạo nhạc", + "musicDesc": "Tạo nhạc và các bản âm thanh qua ComfyUI (Stable Audio, MusicGen)", "moderations": "Kiểm duyệt", "moderationsDesc": "Kiểm duyệt nội dung và phân loại an toàn", - "responsesDesc": "API Responses của OpenAI cho Codex và quy trình làm việc tác tử nâng cao", + "responsesDesc": "API Responses của OpenAI cho Codex và các quy trình làm việc sử dụng tác tử nâng cao", "listModelsDesc": "Liệt kê tất cả các mô hình có sẵn từ tất cả các nhà cung cấp đã kết nối", "settingsApiDesc": "Đọc và sửa đổi cấu hình OmniRoute qua API", - "settingsApi": "Settings API", - "categoryCore": "API Cốt Lõi", - "categoryMedia": "Phương Tiện & Đa Phương Thức", - "categorySearch": "Search & Discovery", - "categoryUtility": "Tiện Ích & Quản Lý", - "webSearch": "Web Search", - "webSearchDesc": "Unified web search across multiple providers with automatic failover and caching", - "searchProvider": "Search Provider", - "searchProviderDesc": "This provider is used for web search via POST /v1/search. No model configuration needed — search providers are ready to use once an API key is connected.", - "enableCloudTitle": "Kích hoạt proxy đám mây", + "settingsApi": "API cài đặt", + "categoryCore": "API cốt lõi", + "categoryMedia": "Đa phương tiện & Đa phương thức", + "categorySearch": "Tìm kiếm & Khám phá", + "categoryUtility": "Tiện ích & Quản lý", + "webSearch": "Tìm kiếm Web", + "webSearchDesc": "Tìm kiếm web hợp nhất trên nhiều nhà cung cấp với tính năng tự động dự phòng (failover) và cache", + "searchProvider": "Nhà cung cấp tìm kiếm", + "searchProviderDesc": "Nhà cung cấp này được sử dụng để tìm kiếm web qua POST /v1/search. Không cần cấu hình mô hình — các nhà cung cấp tìm kiếm sẵn sàng để sử dụng ngay khi kết nối khóa API.", + "enableCloudTitle": "Kích hoạt Cloud Proxy", "whatYouGet": "Những gì bạn sẽ nhận được", "cloudBenefitAccess": "Truy cập API của bạn từ mọi nơi trên thế giới", - "cloudBenefitShare": "Chia sẻ điểm cuối với nhóm của bạn một cách dễ dàng", + "cloudBenefitShare": "Chia sẻ endpoint với nhóm của bạn một cách dễ dàng", "cloudBenefitPorts": "Không cần mở cổng hoặc cấu hình tường lửa", - "cloudBenefitEdge": "Mạng biên toàn cầu nhanh", - "cloudSessionNote": "Cloud sẽ giữ phiên xác thực của bạn trong 1 ngày. Nếu không được sử dụng, nó sẽ tự động bị xóa.", - "cloudUnstableNote": "Cloud hiện tại không ổn định với Claude Code OAuth trong một số trường hợp.", - "cloudConnected": "Đã kết nối Proxy đám mây!", - "connectingToCloud": "Đang kết nối với đám mây...", + "cloudBenefitEdge": "Mạng biên toàn cầu tốc độ cao", + "cloudSessionNote": "Cloud sẽ lưu phiên xác thực của bạn trong 1 ngày. Nếu không được sử dụng, phiên này sẽ tự động bị xóa.", + "cloudUnstableNote": "Cloud hiện không ổn định khi dùng Claude Code OAuth trong một số trường hợp.", + "cloudConnected": "Đã kết nối Cloud Proxy!", + "connectingToCloud": "Đang kết nối với Cloud...", "verifyingConnection": "Đang xác minh kết nối...", "connecting": "Đang kết nối...", "verifying": "Đang xác minh...", "connected": "Đã kết nối!", - "disableCloudTitle": "Vô hiệu hóa Proxy đám mây", - "disableWarning": "Tất cả các phiên xác thực sẽ bị xóa khỏi đám mây.", - "syncingData": "Đang đồng bộ hóa dữ liệu mới nhất...", - "disablingCloud": "Đang tắt đám mây...", - "syncing": "Đang đồng bộ hóa...", - "disabling": "Đang tắt...", + "disableCloudTitle": "Vô hiệu hóa Cloud Proxy", + "disableWarning": "Tất cả các phiên xác thực sẽ bị xóa khỏi Cloud.", + "syncingData": "Đang đồng bộ dữ liệu mới nhất...", + "disablingCloud": "Đang vô hiệu hóa Cloud...", + "syncing": "Đang đồng bộ...", + "disabling": "Đang vô hiệu hóa...", "cloudConnectedVerified": "Cloud Proxy đã được kết nối và xác minh!", - "connectedVerificationPending": "Đã kết nối - đang chờ xác minh", + "connectedVerificationPending": "Đã kết nối — đang chờ xác minh", "connectedVerificationPendingWithError": "Đã kết nối — đang chờ xác minh: {error}", - "cloudDisabledSuccess": "Đám mây đã được tắt thành công", - "syncedSuccess": "Đã đồng bộ hóa thành công", - "failedDisable": "Không thể tắt đám mây", - "failedEnable": "Không thể bật đám mây", - "cloudRequestTimeout": "Hết thời gian yêu cầu đám mây", - "cloudRequestFailed": "Yêu cầu đám mây không thành công", - "cloudWorkerUnreachable": "Không thể liên hệ với nhân viên đám mây. Đảm bảo dịch vụ đám mây đang chạy (npm run dev in /cloud).", - "connectionFailed": "Kết nối không thành công", - "syncFailed": "Không thể đồng bộ hóa dữ liệu đám mây", + "cloudDisabledSuccess": "Đã vô hiệu hóa Cloud thành công", + "syncedSuccess": "Đã đồng bộ thành công", + "failedDisable": "Không thể vô hiệu hóa Cloud", + "failedEnable": "Không thể kích hoạt Cloud", + "cloudRequestTimeout": "Yêu cầu đến Cloud đã hết thời gian chờ", + "cloudRequestFailed": "Yêu cầu đến Cloud không thành công", + "cloudWorkerUnreachable": "Không thể kết nối tới Cloud worker. Đảm bảo dịch vụ Cloud đang chạy (chạy `npm run dev` trong `/cloud`).", + "connectionFailed": "Kết nối thất bại", + "syncFailed": "Không thể đồng bộ dữ liệu Cloud", "cloudflaredTitle": "Cloudflare Quick Tunnel", - "cloudflaredDescription": "Create a Cloudflare Quick Tunnel for this endpoint to make it accessible from the internet without configuring DNS.", - "cloudflaredUrlNotice": "Creates a temporary Cloudflare Quick Tunnel. URLs change after restart.", - "cloudflaredEnable": "Enable Tunnel", - "cloudflaredInstallAndEnable": "Install & Enable", - "cloudflaredDisable": "Stop Tunnel", - "cloudflaredRunning": "Running", - "cloudflaredStarting": "Starting", - "cloudflaredStoppedState": "Stopped", - "cloudflaredNotInstalled": "Not installed", - "cloudflaredUnsupported": "Unsupported", - "cloudflaredError": "Error", - "cloudflaredStarted": "Cloudflare tunnel started", - "cloudflaredStopped": "Cloudflare tunnel stopped", - "cloudflaredRequestFailed": "Failed to update Cloudflare tunnel", - "cloudflaredTemporaryNote": "Quick Tunnel URLs are temporary and will change after restart.", - "cloudflaredUnsupportedNote": "This platform is not supported for managed installation.", - "cloudflaredIdleNote": "Create a temporary Cloudflare Quick Tunnel for this endpoint.", - "cloudflaredLastError": "Last error: {error}", + "cloudflaredDescription": "Tạo một Cloudflare Quick Tunnel cho endpoint này.", + "cloudflaredUrlNotice": "Tạo một Cloudflare Quick Tunnel tạm thời. URL sẽ thay đổi sau mỗi lần khởi động lại.", + "cloudflaredEnable": "Bật Tunnel", + "cloudflaredInstallAndEnable": "Cài đặt & Bật", + "cloudflaredDisable": "Dừng Tunnel", + "cloudflaredRunning": "Đang chạy", + "cloudflaredStarting": "Đang khởi động", + "cloudflaredStoppedState": "Đã dừng", + "cloudflaredNotInstalled": "Chưa cài đặt", + "cloudflaredUnsupported": "Không được hỗ trợ", + "cloudflaredError": "Lỗi", + "cloudflaredStarted": "Đã khởi động đường hầm Cloudflare", + "cloudflaredStopped": "Đã dừng đường hầm Cloudflare", + "cloudflaredRequestFailed": "Không thể cập nhật đường hầm Cloudflare", + "cloudflaredTemporaryNote": "Các URL Quick Tunnel là tạm thời và sẽ thay đổi sau mỗi lần khởi động lại.", + "cloudflaredUnsupportedNote": "Nền tảng này không hỗ trợ cài đặt được quản lý. Hãy cài đặt cloudflared thủ công hoặc trỏ CLOUDFLARED_BIN đến một tệp nhị phân hiện có.", + "cloudflaredIdleNote": "Tạo một Cloudflare Quick Tunnel tạm thời cho endpoint này.", + "cloudflaredLastError": "Lỗi cuối cùng: {error}", "providerModelsTitle": "{provider} — Mô hình", - "noModelsForProvider": "Không có mô hình có sẵn cho nhà cung cấp này.", + "noModelsForProvider": "Không có mô hình nào khả dụng cho nhà cung cấp này.", "chat": "Trò chuyện", "embedding": "Nhúng", "image": "Hình ảnh", "custom": "tùy chỉnh", - "modelsCount": "{count, plural, one {# model} other {# models}}", - "sectionTitle": "Integration Surface", - "sectionDescription": "OpenAI-compatible APIs and operational protocol endpoints", - "tabApis": "OpenAI-compatible APIs", - "tabProtocols": "Protocols", - "tabsAria": "Endpoint sections", - "protocolsTitle": "Protocols", - "protocolsDescription": "MCP and A2A are first-class endpoints with dedicated observability and controls.", - "mcpCardTitle": "MCP Server", - "mcpCardDescription": "Model Context Protocol over stdio", - "a2aCardTitle": "A2A Server", - "a2aCardDescription": "Agent2Agent JSON-RPC endpoint", - "protocolToolsLabel": "Tools", - "protocolTasksLabel": "Tasks", - "protocolActiveStreamsLabel": "Active streams", - "protocolLastActivity": "Last activity", - "quickStart": "Quick Start", - "openMcpDashboard": "Open MCP management", - "openA2aDashboard": "Open A2A management", - "mcpQuickStartTitle": "MCP Quick Start", - "mcpQuickStartStep1": "Run the MCP server via `omniroute --mcp`.", - "mcpQuickStartStep2": "Configure your MCP client to connect over stdio transport.", - "mcpQuickStartStep3": "Invoke tools such as `omniroute_get_health` and `omniroute_list_combos`.", - "a2aQuickStartTitle": "A2A Quick Start", - "a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.", - "a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.", - "a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.", - "completionsLegacy": "Completions (Legacy)", - "completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format", + "modelsCount": "{count, plural, one {# mô hình} other {# mô hình}}", + "sectionTitle": "Giao diện tích hợp", + "sectionDescription": "API tương thích với OpenAI và các endpoint của giao thức vận hành", + "tabApis": "API", + "tabProtocols": "Giao thức", + "tabsAria": "Các phần của endpoint", + "protocolsTitle": "Giao thức", + "protocolsDescription": "MCP và A2A là các endpoint được hỗ trợ đầy đủ, với khả năng giám sát và kiểm soát chuyên biệt.", + "mcpCardTitle": "Máy chủ MCP", + "mcpCardDescription": "Model Context Protocol qua stdio", + "a2aCardTitle": "Máy chủ A2A", + "a2aCardDescription": "Endpoint JSON-RPC cho Agent2Agent", + "protocolToolsLabel": "Công cụ", + "protocolTasksLabel": "Nhiệm vụ", + "protocolActiveStreamsLabel": "Các luồng đang hoạt động", + "protocolLastActivity": "Hoạt động cuối cùng", + "quickStart": "Bắt đầu nhanh", + "openMcpDashboard": "Mở trình quản lý MCP", + "openA2aDashboard": "Mở trình quản lý A2A", + "mcpQuickStartTitle": "Bắt đầu nhanh với MCP", + "mcpQuickStartStep1": "Chạy máy chủ MCP bằng lệnh `omniroute --mcp`.", + "mcpQuickStartStep2": "Cấu hình ứng dụng khách MCP của bạn để kết nối qua phương thức truyền tải stdio.", + "mcpQuickStartStep3": "Gọi các công cụ như `omniroute_get_health` và `omniroute_list_combos`.", + "a2aQuickStartTitle": "Bắt đầu nhanh với A2A", + "a2aQuickStartStep1": "Tìm thẻ tác nhân tại `/.well-known/agent.json`.", + "a2aQuickStartStep2": "Gửi các yêu cầu JSON-RPC đến `POST /a2a` bằng cách sử dụng `message/send` hoặc `message/stream`.", + "a2aQuickStartStep3": "Theo dõi và kiểm soát các nhiệm vụ bằng cách sử dụng `tasks/get` và `tasks/cancel`.", + "completionsLegacy": "Completions (Bản cũ)", + "completionsLegacyDesc": "Hoàn thành văn bản OpenAI kiểu cũ — chấp nhận cả chuỗi prompt và định dạng mảng tin nhắn", "messagesApi": "Tin nhắn", - "messagesApiDesc": "Định dạng API thông điệp nhân loại gốc dành cho các nhà cung cấp tương thích với Claude", + "messagesApiDesc": "Định dạng Messages API của Anthropic gốc dành cho các nhà cung cấp tương thích với Claude", "imageEdits": "Chỉnh sửa hình ảnh", - "imageEditsDesc": "Chỉnh sửa và sửa đổi các hình ảnh hiện có bằng AI (inpainting, outpainting, các biến thể)", + "imageEditsDesc": "Chỉnh sửa và thay đổi hình ảnh hiện có bằng AI (inpainting, outpainting, các biến thể)", "batchApi": "API hàng loạt", - "batchApiDesc": "Xử lý hàng loạt yêu cầu lớn không đồng bộ (tương thích với OpenAI)", + "batchApiDesc": "Xử lý không đồng bộ các lô yêu cầu lớn (tương thích với OpenAI)", "filesApi": "API tệp", - "filesApiDesc": "Tải lên và quản lý tập tin để xử lý hàng loạt", - "videoGeneration": "Video Generation", - "videoDesc": "Generate videos using AI models like ComfyUI and Stable Video Diffusion.", - "tailscaleRequestFailed": "Failed to load Tailscale status", - "tailscaleEnableFailed": "Failed to enable Tailscale Funnel", - "tailscaleWaitingForLogin": "Complete the Tailscale login in the opened browser tab. OmniRoute will retry automatically.", - "tailscaleLoginTimedOut": "Timed out waiting for Tailscale login", - "tailscaleWaitingForFunnel": "Enable Funnel for this device in the opened browser tab. OmniRoute will keep polling.", - "tailscaleFunnelTimedOut": "Timed out waiting for Tailscale Funnel to be enabled", - "tailscaleStarted": "Tailscale Funnel enabled", - "tailscaleDisableFailed": "Failed to disable Tailscale Funnel", - "tailscaleStopped": "Tailscale Funnel disabled", - "tailscaleInstallFailed": "Failed to install Tailscale", - "tailscaleInstallProgress": "Working...", - "tailscaleInstalled": "Tailscale installed successfully", - "tailscaleRunning": "Running", - "tailscaleNeedsLogin": "Needs Login", - "tailscaleStoppedState": "Stopped", - "tailscaleNotInstalled": "Not installed", - "tailscaleUnsupported": "Unsupported", - "tailscaleError": "Error", - "tailscaleDisable": "Stop Funnel", - "tailscaleInstallAndEnable": "Install & Enable", - "tailscaleLoginAndEnable": "Login & Enable", - "tailscaleEnable": "Enable Funnel", - "tailscaleUrlNotice": "Uses your Tailscale .ts.net address. Login and Funnel approval may be required on first use.", + "filesApiDesc": "Tải lên và quản lý các tệp để xử lý hàng loạt", + "videoGeneration": "Tạo video", + "videoDesc": "Tạo video bằng các mô hình AI như ComfyUI và Stable Video Diffusion.", + "tailscaleRequestFailed": "Không thể tải trạng thái Tailscale", + "tailscaleEnableFailed": "Không thể bật Tailscale Funnel", + "tailscaleWaitingForLogin": "Hoàn tất đăng nhập Tailscale trong tab trình duyệt đã mở. OmniRoute sẽ tự động thử lại.", + "tailscaleLoginTimedOut": "Đã hết thời gian chờ đăng nhập Tailscale", + "tailscaleWaitingForFunnel": "Bật Funnel cho thiết bị này trong tab trình duyệt đã mở. OmniRoute sẽ tiếp tục kiểm tra định kỳ.", + "tailscaleFunnelTimedOut": "Đã hết thời gian chờ để bật Tailscale Funnel", + "tailscaleStarted": "Đã bật Tailscale Funnel", + "tailscaleDisableFailed": "Không thể tắt Tailscale Funnel", + "tailscaleStopped": "Đã tắt Tailscale Funnel", + "tailscaleInstallFailed": "Không thể cài đặt Tailscale", + "tailscaleInstallProgress": "Đang xử lý...", + "tailscaleInstalled": "Đã cài đặt Tailscale thành công", + "tailscaleRunning": "Đang chạy", + "tailscaleNeedsLogin": "Cần đăng nhập", + "tailscaleStoppedState": "Đã dừng", + "tailscaleNotInstalled": "Chưa cài đặt", + "tailscaleUnsupported": "Không được hỗ trợ", + "tailscaleError": "Lỗi", + "tailscaleDisable": "Dừng Funnel", + "tailscaleInstallAndEnable": "Cài đặt & Bật", + "tailscaleLoginAndEnable": "Đăng nhập & Bật", + "tailscaleEnable": "Bật Funnel", + "tailscaleUrlNotice": "Sử dụng địa chỉ .ts.net của Tailscale. Có thể cần đăng nhập và phê duyệt Funnel trong lần sử dụng đầu tiên.", "tailscaleTitle": "Tailscale Funnel", - "tailscaleNeedsLoginHint": "Authenticate this machine with Tailscale, then enable Funnel.", - "tailscaleBinaryPath": "Binary: {path}", - "tailscaleLastError": "Last error: {error}", - "tailscaleInstallTitle": "Install Tailscale", - "tailscaleInstallIntro": "Installs Tailscale on this machine and prepares OmniRoute to enable Funnel.", - "tailscaleInstallPasswordHint": "On macOS and Linux, sudo may be required for the package install and daemon start.", - "tailscaleSudoPlaceholder": "Optional sudo password", - "tailscaleInstalling": "Installing", - "tailscaleSudoLabel": "Mật khẩu Sudo (bắt buộc trên macOS/Linux)", - "ngrokTitle": "đường hầm ngrok", + "tailscaleNeedsLoginHint": "Xác thực máy này với Tailscale, sau đó bật Funnel.", + "tailscaleBinaryPath": "Tệp thực thi: {path}", + "tailscaleLastError": "Lỗi cuối cùng: {error}", + "tailscaleInstallTitle": "Cài đặt Tailscale", + "tailscaleInstallIntro": "Cài đặt Tailscale trên máy này và chuẩn bị OmniRoute cho việc bật Funnel.", + "tailscaleInstallPasswordHint": "Trên macOS và Linux, có thể cần sudo để cài đặt gói và khởi động daemon.", + "tailscaleSudoPlaceholder": "Mật khẩu sudo tùy chọn", + "tailscaleInstalling": "Đang cài đặt", + "tailscaleSudoLabel": "Mật khẩu sudo (bắt buộc trên macOS/Linux)", + "ngrokTitle": "Đường hầm ngrok", "ngrokRunning": "Đang chạy", - "ngrokStarting": "Bắt đầu", + "ngrokStarting": "Đang khởi động", "ngrokStoppedState": "Đã dừng", "ngrokNeedsAuth": "Cần xác thực", - "ngrokNotInstalled": "Chưa được cài đặt", + "ngrokNotInstalled": "Chưa cài đặt", "ngrokUnsupported": "Không được hỗ trợ", "ngrokError": "Lỗi", - "ngrokEnable": "Kích hoạt đường hầm", - "ngrokDisable": "Đường hầm dừng", - "ngrokUrlNotice": "Tạo một đường hầm ngrok công cộng.", - "ngrokAuthTokenLabel": "Authtoken (Bắt buộc nếu NGROK_AUTHTOKEN chưa được đặt)", - "ngrokAuthTokenPlaceholder": "Nhập mã xác thực ngrok của bạn", + "ngrokEnable": "Bật đường hầm", + "ngrokDisable": "Dừng đường hầm", + "ngrokUrlNotice": "Tạo một đường hầm ngrok công khai.", + "ngrokAuthTokenLabel": "Authtoken (Bắt buộc nếu chưa đặt NGROK_AUTHTOKEN)", + "ngrokAuthTokenPlaceholder": "Nhập authtoken ngrok của bạn", "ngrokLastError": "Lỗi cuối cùng: {error}", - "ngrokStarted": "đường hầm ngrok bắt đầu", - "ngrokStopped": "đường hầm ngrok đã dừng lại", + "ngrokStarted": "Đường hầm ngrok đã khởi động", + "ngrokStopped": "Đường hầm ngrok đã dừng", "ngrokRequestFailed": "Không thể cập nhật đường hầm ngrok", - "tokenSaverSubtitle": "Chi tiêu ít mã thông báo hơn cho mỗi yêu cầu.", - "tokenSaverToolOutput": "Đầu ra công cụ", - "tokenSaverLlmOutput": "Đầu ra LLM", - "tokenSaverInputCompression": "nén đầu vào", - "apiEndpointsCatalogUnavailable": "Danh mục API không có sẵn", - "apiEndpointsSearchPlaceholder": "Tìm kiếm điểm cuối...", + "apiEndpointsCatalogUnavailable": "Danh mục API không khả dụng", + "apiEndpointsSearchPlaceholder": "Tìm kiếm endpoint...", "apiEndpointsRequiresAuth": "Yêu cầu xác thực", - "apiEndpointsNoMatch": "Không có điểm cuối nào khớp với bộ lọc của bạn", + "apiEndpointsNoMatch": "Không có endpoint nào khớp với bộ lọc của bạn", "localServer": "Máy chủ cục bộ", "cloudOmniroute": "Cloud OmniRoute", "copyUrl": "Sao chép URL", - "badgeLoopbackTooltip": "__MISSING__:This endpoint is only accessible locally (loopback only)", - "badgeAlwaysProtectedTooltip": "__MISSING__:This endpoint is always protected and requires authorization", - "badgeInternalTooltip": "__MISSING__:This is an internal system endpoint", - "tierAll": "__MISSING__:All", - "tierAuth": "__MISSING__:Authenticated", - "tierLoopback": "__MISSING__:Loopback", - "tierAlwaysProtected": "__MISSING__:Always Protected", - "tierPublic": "__MISSING__:Public", - "hideInternal": "__MISSING__:Hide Internal", - "showInternal": "__MISSING__:Show Internal", - "customSystemPromptTitle": "Custom System Prompt", - "customSystemPromptDescription": "Inject a custom system prompt into every model request", - "customSystemPromptPlaceholder": "e.g. Always respond in pirate speak..." + "badgeLoopbackTooltip": "Endpoint này chỉ có thể truy cập cục bộ (chỉ loopback)", + "badgeAlwaysProtectedTooltip": "Endpoint này luôn được bảo vệ và yêu cầu ủy quyền", + "badgeInternalTooltip": "Đây là một endpoint hệ thống nội bộ", + "tierAll": "Tất cả", + "tierAuth": "Đã xác thực", + "tierLoopback": "Loopback", + "tierAlwaysProtected": "Luôn được bảo vệ", + "tierPublic": "Công khai", + "hideInternal": "Ẩn nội bộ", + "showInternal": "Hiện nội bộ", + "customSystemPromptTitle": "Lời nhắc hệ thống tùy chỉnh", + "customSystemPromptDescription": "Chèn lời nhắc hệ thống tùy chỉnh vào mọi yêu cầu mô hình", + "customSystemPromptPlaceholder": "Ví dụ: Luôn trả lời bằng giọng cướp biển...", + "vscodeAliasTitle": "VS Code Token Alias", + "vscodeAliasDescriptionReady": "Ready-to-paste compatibility URLs using the /api/v1/vscode/TOKEN/... endpoint.", + "vscodeAliasDescriptionError": "Showing placeholder URLs because CLI keys could not be loaded in this session.", + "vscodeAliasDescriptionLoading": "Loading CLI keys. Placeholder URLs are shown until a key is available.", + "vscodeAliasDescriptionPlaceholder": "Showing placeholder URLs. Create or activate an API key in CLI Tools to replace TOKEN.", + "vscodeAliasManage": "CLI Tools", + "vscodeAliasBaseLabel": "VS Code base", + "vscodeAliasModelsLabel": "VS Code models", + "vscodeAliasChatLabel": "VS Code chat" }, "endpoints": { "tabProxy": "Endpoint Proxy", "tabApiEndpoints": "API Endpoints", "apiEndpointsTitle": "API Endpoints", - "apiEndpointsDescription": "Backend API endpoints that can be consumed by other applications and services. This section will list all available REST APIs with documentation and testing capabilities.", - "comingSoon": "Coming Soon", - "plannedFeatures": "Planned Features", - "featureRestApi": "REST API endpoint catalog with interactive documentation", - "featureWebhooks": "Webhook configuration and event subscriptions", - "featureSwagger": "OpenAPI / Swagger spec auto-generation", - "featureAuth": "API key and OAuth scope management per endpoint" + "apiEndpointsDescription": "Các điểm cuối API phụ trợ mà các ứng dụng và dịch vụ khác có thể sử dụng. Phần này sẽ liệt kê tất cả REST API hiện có, kèm tài liệu hướng dẫn và tính năng kiểm thử.", + "comingSoon": "Sắp ra mắt", + "plannedFeatures": "Các tính năng dự kiến", + "featureRestApi": "Danh mục REST API endpoint với tài liệu tương tác", + "featureWebhooks": "Cấu hình webhook và đăng ký nhận sự kiện", + "featureSwagger": "Tự động tạo đặc tả OpenAPI / Swagger", + "featureAuth": "Quản lý khóa API và phạm vi OAuth cho từng endpoint" }, "mcpDashboard": { - "loading": "Loading MCP dashboard...", - "activate": "activate", - "deactivate": "deactivate", - "confirmSwitchCombo": "Confirm {action} combo \"{combo}\"?", - "switchComboFailed": "Failed to switch combo state.", - "switchComboSuccess": "Combo \"{combo}\" updated.", - "confirmApplyProfile": "Apply resilience profile \"{profile}\"?", - "applyProfileFailed": "Failed to apply resilience profile.", - "applyProfileSuccess": "Profile \"{profile}\" applied.", - "confirmResetBreakers": "Reset all circuit breakers?", - "resetBreakersFailed": "Failed to reset circuit breakers.", - "resetBreakersSuccess": "Circuit breakers reset.", - "processStatus": "Process status", - "online": "Online", - "offline": "Offline", - "disableLabel": "__MISSING__:Disable {label}", - "enableLabel": "__MISSING__:Enable {label}", - "transportMode": "__MISSING__:Transport Mode", - "transportStdioDesc": "__MISSING__:Local — IDE spawns process via omniroute --mcp", - "transportSseDesc": "__MISSING__:Remote — Server-Sent Events over HTTP", - "transportStreamableHttpDesc": "__MISSING__:Remote — Modern bidirectional HTTP", - "copy": "__MISSING__:Copy", + "loading": "Đang tải bảng điều khiển MCP...", + "activate": "kích hoạt", + "deactivate": "hủy kích hoạt", + "confirmSwitchCombo": "Xác nhận {action} tổ hợp \"{combo}\"?", + "switchComboFailed": "Không thể chuyển đổi trạng thái tổ hợp.", + "switchComboSuccess": "Tổ hợp \"{combo}\" đã được cập nhật.", + "confirmApplyProfile": "Áp dụng cấu hình khả năng phục hồi \"{profile}\"?", + "applyProfileFailed": "Không thể áp dụng cấu hình khả năng phục hồi.", + "applyProfileSuccess": "Đã áp dụng cấu hình \"{profile}\".", + "confirmResetBreakers": "Đặt lại tất cả bộ ngắt mạch?", + "resetBreakersFailed": "Không thể đặt lại các bộ ngắt mạch.", + "resetBreakersSuccess": "Đã đặt lại các bộ ngắt mạch.", + "processStatus": "Trạng thái tiến trình", + "online": "Trực tuyến", + "offline": "Ngoại tuyến", + "disableLabel": "Vô hiệu hóa {label}", + "enableLabel": "Kích hoạt {label}", + "transportMode": "Chế độ truyền tải", + "transportStdioDesc": "Cục bộ — IDE khởi chạy tiến trình bằng omniroute --mcp", + "transportSseDesc": "Từ xa — Server-Sent Events qua HTTP", + "transportStreamableHttpDesc": "Từ xa — HTTP hai chiều hiện đại", + "copy": "Sao chép", "mcpDashboardCopyUrl": "Sao chép URL", - "mcpDisabledTitle": "__MISSING__:MCP is disabled", - "mcpDisabledDesc": "__MISSING__:Enable MCP above to configure transport mode and view server telemetry.", - "mcpIntro": "__MISSING__:Model Context Protocol — {tools} tools across {scopes} scopes, {transports} transports (stdio / SSE / Streamable HTTP).", - "mcpStep1": "__MISSING__:Run via {code}", - "mcpStep2": "__MISSING__:Configure your MCP client to connect over stdio transport.", - "mcpStep3": "__MISSING__:Invoke tools like {code1} and {code2}.", + "mcpDisabledTitle": "MCP bị vô hiệu hóa", + "mcpDisabledDesc": "Kích hoạt MCP ở trên để cấu hình chế độ truyền tải và xem dữ liệu đo từ xa của máy chủ.", + "mcpIntro": "Model Context Protocol — {tools} công cụ thuộc {scopes} phạm vi, {transports} phương thức truyền tải (stdio / SSE / Streamable HTTP).", + "mcpStep1": "Chạy thông qua {code}", + "mcpStep2": "Cấu hình ứng dụng khách MCP để kết nối qua phương thức truyền tải stdio.", + "mcpStep3": "Gọi các công cụ như {code1} và {code2}.", "pid": "PID", - "sessionUptime": "Session uptime", - "lastHeartbeat": "Last heartbeat", - "activity24h": "Activity (24h)", - "totalCalls": "Total calls", - "successRate": "Success rate", - "avgLatency": "Avg latency", - "topTools": "Top tools", - "noToolCalls24h": "No tool calls in the last 24 hours.", - "runtimeDetails": "Runtime details", - "transport": "Transport", - "scopesEnforced": "Scopes enforced", - "yes": "yes", - "no": "no", - "lastCall": "Last call", - "heartbeatPath": "Heartbeat path", - "operationalControls": "Operational controls", - "switchCombo": "Switch combo", - "inactive": "inactive", - "active": "active", - "activateCombo": "Activate combo", - "deactivateCombo": "Deactivate combo", - "applyResilienceProfile": "Apply resilience profile", - "profileAggressive": "aggressive", - "profileBalanced": "balanced", - "profileConservative": "conservative", - "applyProfile": "Apply profile", - "resetCircuitBreakers": "Reset circuit breakers", - "resetCircuitBreakersHelp": "Clears current breaker state and failure counters for providers.", - "resetAllBreakers": "Reset all breakers", - "toolsAndScopes": "Tools and scopes", - "tableTool": "Tool", - "tableScopes": "Scopes", - "tablePhase": "Phase", - "tableAudit": "Audit", - "auditLog": "Audit log", - "auditSummary": "Calls: {total} | page {page} of {totalPages}", - "allTools": "All tools", - "allResults": "All results", - "success": "Success", - "failure": "Failure", + "sessionUptime": "Thời gian hoạt động của phiên", + "lastHeartbeat": "Tín hiệu hoạt động gần nhất", + "activity24h": "Hoạt động (24 giờ)", + "totalCalls": "Tổng số lệnh gọi", + "successRate": "Tỷ lệ thành công", + "avgLatency": "Độ trễ trung bình", + "topTools": "Các công cụ được dùng nhiều nhất", + "noToolCalls24h": "Không có lệnh gọi công cụ nào trong 24 giờ qua.", + "runtimeDetails": "Chi tiết thời gian chạy", + "transport": "Phương thức truyền tải", + "scopesEnforced": "Phạm vi được áp dụng", + "yes": "có", + "no": "không", + "lastCall": "Lệnh gọi gần nhất", + "heartbeatPath": "Đường dẫn tín hiệu hoạt động", + "operationalControls": "Các điều khiển vận hành", + "switchCombo": "Chuyển đổi tổ hợp", + "inactive": "không hoạt động", + "active": "hoạt động", + "activateCombo": "Kích hoạt tổ hợp", + "deactivateCombo": "Hủy kích hoạt tổ hợp", + "applyResilienceProfile": "Áp dụng cấu hình khả năng phục hồi", + "profileAggressive": "mạnh mẽ", + "profileBalanced": "cân bằng", + "profileConservative": "thận trọng", + "applyProfile": "Áp dụng cấu hình", + "resetCircuitBreakers": "Đặt lại bộ ngắt mạch", + "resetCircuitBreakersHelp": "Xóa trạng thái hiện tại của các bộ ngắt mạch và bộ đếm lỗi của nhà cung cấp.", + "resetAllBreakers": "Đặt lại tất cả bộ ngắt mạch", + "toolsAndScopes": "Công cụ và phạm vi", + "tableTool": "Công cụ", + "tableScopes": "Phạm vi", + "tablePhase": "Giai đoạn", + "tableAudit": "Kiểm toán", + "auditLog": "Nhật ký kiểm toán", + "auditSummary": "Cuộc gọi: {total} | trang {page} / {totalPages}", + "allTools": "Tất cả công cụ", + "allResults": "Tất cả kết quả", + "success": "Thành công", + "failure": "Thất bại", "apiKeyIdPlaceholder": "apiKeyId", - "loadingAuditEntries": "Loading audit entries...", - "noAuditEntriesForFilters": "No audit entries found for current filters.", - "tableTimestamp": "Timestamp", - "tableDuration": "Duration", - "tableResult": "Result", - "tableApiKey": "API key", - "failed": "failed", - "previous": "Previous", - "next": "Next", - "apiKeyId": "Api Key Id", - "offset": "Offset", - "limit": "Limit", - "tool": "Tool" + "loadingAuditEntries": "Đang tải các bản ghi kiểm toán...", + "noAuditEntriesForFilters": "Không tìm thấy bản ghi kiểm toán nào cho các bộ lọc hiện tại.", + "tableTimestamp": "Mốc thời gian", + "tableDuration": "Thời lượng", + "tableResult": "Kết quả", + "tableApiKey": "Khóa API", + "failed": "thất bại", + "previous": "Trước", + "next": "Tiếp theo", + "apiKeyId": "ID khóa API", + "offset": "Độ lệch", + "limit": "Giới hạn", + "tool": "Công cụ" }, "a2aDashboard": { - "loading": "Loading A2A dashboard...", - "confirmCancelTask": "Cancel task {taskId}?", - "cancelTaskFailed": "Failed to cancel task.", - "cancelTaskSuccess": "Task {taskId} cancelled.", - "smokeSendFailed": "message/send smoke test failed.", - "smokeSendSuccessWithTask": "message/send ok (task {taskId}).", - "smokeSendSuccess": "message/send ok.", - "smokeStreamFailed": "message/stream smoke test failed.", - "smokeStreamSuccessWithTask": "message/stream ok (task {taskId}{stateSuffix}).", - "smokeStreamNoTaskId": "message/stream finished without task id.", - "health": "Health", - "ok": "ok", - "totalTasks": "Total tasks", - "activeStreams": "Active streams", - "lastTask": "Last task", - "taskStateOverview": "Task state overview", + "loading": "Đang tải bảng điều khiển A2A...", + "confirmCancelTask": "Hủy tác vụ {taskId}?", + "cancelTaskFailed": "Không thể hủy tác vụ.", + "cancelTaskSuccess": "Tác vụ {taskId} đã bị hủy.", + "smokeSendFailed": "Kiểm tra nhanh message/send thất bại.", + "smokeSendSuccessWithTask": "message/send thành công (tác vụ {taskId}).", + "smokeSendSuccess": "message/send thành công.", + "smokeStreamFailed": "Kiểm tra nhanh message/stream thất bại.", + "smokeStreamSuccessWithTask": "message/stream thành công (tác vụ {taskId}{stateSuffix}).", + "smokeStreamNoTaskId": "message/stream kết thúc mà không có ID tác vụ.", + "health": "Trạng thái", + "ok": "hoạt động tốt", + "totalTasks": "Tổng số tác vụ", + "activeStreams": "Các luồng đang hoạt động", + "lastTask": "Tác vụ gần nhất", + "taskStateOverview": "Tổng quan trạng thái tác vụ", "state": { - "submitted": "submitted", - "working": "working", - "completed": "completed", - "failed": "failed", - "cancelled": "cancelled" + "submitted": "đã gửi", + "working": "đang xử lý", + "completed": "đã hoàn thành", + "failed": "thất bại", + "cancelled": "đã hủy" }, - "agentCard": "Agent card", - "agentCardPath": "__MISSING__:/.well-known/agent.json", - "version": "Version", + "agentCard": "Thẻ tác nhân", + "agentCardPath": "/.well-known/agent.json", + "version": "Phiên bản", "url": "URL", - "capabilities": "Capabilities", - "agentCardNotAvailable": "Agent card not available.", - "quickValidation": "Quick validation", - "quickValidationDescription": "Executes smoke calls through the live `/a2a` endpoint.", - "runMessageSend": "Run message/send", - "runMessageStream": "Run message/stream", - "taskManagement": "Task management", - "taskSummary": "{total} tasks | page {page} of {totalPages}", - "allStates": "all", - "allSkills": "all skills", - "loadingTasks": "Loading tasks...", - "noTasksForFilters": "No tasks found for current filters.", - "tableTask": "Task", - "tableSkill": "Skill", - "tableState": "State", - "tableUpdated": "Updated", - "tableActions": "Actions", - "view": "View", - "cancel": "Cancel", - "previous": "Previous", - "next": "Next", - "taskDetail": "Task detail", - "close": "Close", - "metadata": "Metadata", - "events": "Events", - "artifacts": "Artifacts", - "tablePhase": "Table Phase", - "offset": "Offset", - "limit": "Limit", - "skill": "Skill", - "rpcEndpoint": "BÀI ĐĂNG /a2a", - "rpcMethodSend": "tin nhắn/gửi", - "rpcMethodStream": "tin nhắn/luồng", - "rpcMethodGet": "nhiệm vụ/nhận", - "rpcMethodCancel": "nhiệm vụ/hủy bỏ", + "capabilities": "Khả năng", + "agentCardNotAvailable": "Thẻ tác nhân không khả dụng.", + "quickValidation": "Xác thực nhanh", + "quickValidationDescription": "Thực hiện các lệnh gọi kiểm tra nhanh thông qua endpoint `/a2a` đang hoạt động.", + "runMessageSend": "Chạy message/send", + "runMessageStream": "Chạy message/stream", + "taskManagement": "Quản lý tác vụ", + "taskSummary": "{total} tác vụ | trang {page} / {totalPages}", + "allStates": "tất cả", + "allSkills": "tất cả kỹ năng", + "loadingTasks": "Đang tải tác vụ...", + "noTasksForFilters": "Không tìm thấy tác vụ nào cho bộ lọc hiện tại.", + "tableTask": "Tác vụ", + "tableSkill": "Kỹ năng", + "tableState": "Trạng thái", + "tableUpdated": "Đã cập nhật", + "tableActions": "Hành động", + "view": "Xem", + "cancel": "Hủy", + "previous": "Tiếp theo", + "next": "Tiếp", + "taskDetail": "Chi tiết tác vụ", + "close": "Đóng", + "metadata": "Siêu dữ liệu", + "events": "Sự kiện", + "artifacts": "Tạo tác", + "tablePhase": "Giai đoạn của bảng", + "offset": "Độ lệch", + "limit": "Giới hạn", + "skill": "Kỹ năng", + "rpcEndpoint": "POST /a2a", + "rpcMethodSend": "message/send", + "rpcMethodStream": "message/stream", + "rpcMethodGet": "tasks/get", + "rpcMethodCancel": "tasks/cancel", "serviceLabel": "A2A", - "online": "__MISSING__:Online", - "offline": "__MISSING__:Offline", - "disableLabel": "__MISSING__:Disable {label}", - "enableLabel": "__MISSING__:Enable {label}", - "a2aDisabledTitle": "__MISSING__:A2A is disabled", - "a2aDisabledDesc": "__MISSING__:Enable A2A above to view task telemetry, agent details, and validation tools.", - "a2aIntro": "__MISSING__:Agent2Agent JSON-RPC 2.0 endpoint — send tasks, stream responses, cancel in-flight jobs.", - "a2aStep1": "__MISSING__:Discover the agent card at {code}.", - "a2aStep2": "__MISSING__:Send JSON-RPC to {code1} using {code2} or {code3}.", - "a2aStep3": "__MISSING__:Track and cancel tasks with {code1} and {code2}." + "online": "Trực tuyến", + "offline": "Ngoại tuyến", + "disableLabel": "Vô hiệu hóa {label}", + "enableLabel": "Kích hoạt {label}", + "a2aDisabledTitle": "A2A đã bị vô hiệu hóa", + "a2aDisabledDesc": "Kích hoạt A2A ở trên để xem dữ liệu giám sát tác vụ, thông tin chi tiết về tác nhân và các công cụ xác thực.", + "a2aIntro": "Endpoint Agent2Agent JSON-RPC 2.0 — gửi tác vụ, truyền phản hồi theo luồng, hủy các công việc đang thực hiện.", + "a2aStep1": "Tìm thẻ tác nhân tại {code}.", + "a2aStep2": "Gửi JSON-RPC đến {code1} bằng {code2} hoặc {code3}.", + "a2aStep3": "Theo dõi và hủy các nhiệm vụ bằng {code1} và {code2}." }, "memory": { - "title": "Memory Management", - "description": "View and manage stored memory entries", - "memories": "Memories", - "totalEntries": "Total Entries", - "tokensUsed": "Tokens Used", - "hitRate": "Hit Rate", - "loading": "Loading memories...", - "noMemories": "No memories found", - "search": "Search memories...", - "allTypes": "All Types", - "export": "Export", - "import": "Import", - "addMemory": "Add Memory", - "type": "Type", - "key": "Key", - "content": "Content", - "created": "Created", - "actions": "Actions", - "delete": "Delete", - "factual": "Factual", - "episodic": "Episodic", - "procedural": "Procedural", - "semantic": "Semantic", + "title": "Quản lý ký ức", + "description": "Xem và quản lý các mục bộ nhớ đã lưu trữ", + "memories": "Bộ nhớ", + "totalEntries": "Tổng số mục", + "tokensUsed": "Số token đã dùng", + "hitRate": "Tỷ lệ khớp", + "loading": "Đang tải...", + "noMemories": "Không tìm thấy bộ nhớ nào", + "search": "Tìm kiếm ký ức...", + "allTypes": "Tất cả các loại", + "export": "Xuất", + "import": "Nhập", + "addMemory": "Thêm bộ nhớ", + "type": "Loại", + "key": "Khóa", + "content": "Nội dung", + "created": "Đã tạo", + "actions": "Hành động", + "delete": "Xóa", + "factual": "Thực tế", + "episodic": "Tình tiết", + "procedural": "Quy trình", + "semantic": "Ngữ nghĩa", "a": "A", - "pipelineOk": "Đường ống ổn ({latencyMs}ms)", - "pipelineError": "Lỗi đường ống", - "healthUnknown": "Không rõ sức khỏe", + "pipelineOk": "Quy trình xử lý hoạt động tốt ({latencyMs}ms)", + "pipelineError": "Lỗi quy trình xử lý", + "healthUnknown": "Không rõ trạng thái hoạt động", "checkingHealth": "Đang kiểm tra…", - "checkHealth": "Kiểm tra sức khỏe", + "checkHealth": "Kiểm tra tình trạng", "pageInfo": "Trang {page} trên {totalPages} (tổng cộng {total})", - "previous": "trước đó", + "previous": "Trước đó", "next": "Tiếp theo", - "cancel": "Hủy bỏ", + "cancel": "Hủy", "save": "Lưu", "keyPlaceholder": "ví dụ: user.preferences.theme", - "contentPlaceholder": "Giá trị hoặc nội dung JSON cần ghi nhớ" + "contentPlaceholder": "Giá trị hoặc nội dung JSON cần ghi nhớ", + "compactOld": "Compact old", + "concept": { + "title": "Conversational Memory", + "description": "OmniRoute learns from every conversation, remembering facts, episodes, procedures, and semantic concepts that make responses more accurate and context-aware.", + "howWorksToggle": "How it works", + "howWorksContent": "1. Automatic extraction: at the end of each response, facts and episodes are detected and saved automatically.\n2. Retrieval: before each response, the most relevant memories are searched via FTS5 (exact), vector (semantic), or hybrid RRF.\n3. Injection: relevant memories are injected into the assistant context to improve response quality.\n4. Management: use this page to view, edit, export, and compact old memories." + }, + "deleteConfirmDesc": "This action cannot be undone. The memory will be permanently removed.", + "deleteConfirmTitle": "Delete memory?", + "editMemory": "Edit memory", + "editModal": { + "title": "Edit Memory", + "metadataLabel": "Metadata (JSON)", + "metadataInvalid": "Invalid JSON", + "saveFailed": "Failed to save memory" + }, + "embedding": { + "autoLabel": "Automatic", + "autoDesc": "Uses best available: remote provider > static > transformers", + "remoteLabel": "Remote provider", + "remoteDesc": "Uses embedding via provider API (requires API key)", + "staticLabel": "Static local (potion)", + "staticDesc": "Local embedding without WASM or external dependencies", + "transformersLabel": "Transformers.js (MiniLM)", + "transformersDesc": "Local embedding via @huggingface/transformers (~400MB RAM)", + "providerModelLabel": "Provider / Model", + "noRemoteProviders": "No providers with configured API key", + "selectProviderModel": "Select a model", + "staticEnabledLabel": "Enable Static Potion", + "staticEnabledDesc": "Download and use potion-base-8M model locally", + "transformersEnabledLabel": "Enable Transformers.js", + "transformersEnabledDesc": "Opt-in for local MiniLM (~400MB RAM, ~3s cold start)", + "transformersWarning": "Requires ~400MB RAM and ~3s cold start on the first semantic query." + }, + "emptyState": { + "title": "No memories yet", + "description": "Memories are created automatically from conversations. You can also add them manually using the button above." + }, + "engine": { + "statusTitle": "Engine Status", + "embeddingTitle": "Embedding Source", + "rerankTitle": "Rerank (optional)", + "reindexNow": "Reindex now", + "reindexStarted": "Reindexing started ({pending} pending)", + "reindexFailed": "Failed to start reindexing", + "keywordLabel": "Keyword (FTS5)", + "keywordReason": "Keyword search always available", + "embeddingLabel": "Embedding", + "vectorStoreLabel": "Vector Store", + "qdrantLabel": "Qdrant", + "rerankLabel": "Rerank", + "qdrantDisabled": "Disabled", + "qdrantOk": "Healthy ({latencyMs}ms)", + "qdrantError": "Connection error", + "needsReindex": "{count} memory(ies) need reindexing", + "configureCta": "Configure", + "vectorStoreInstallHint": "To enable vector search: npm install sqlite-vec (needs native Node.js, not WASM), then restart." + }, + "importError": "Failed to import file", + "importResult": "{imported} imported, {skipped} skipped", + "playground": { + "infoTitle": "Memory Playground", + "infoDesc": "Simulate what would be retrieved for a given query. No memories are modified — read-only preview.", + "queryLabel": "Test query", + "queryPlaceholder": "Type a question or test phrase...", + "strategyLabel": "Strategy", + "strategyExact": "Exact (FTS5)", + "strategySemantic": "Semantic (vector)", + "strategyHybrid": "Hybrid (RRF)", + "budgetLabel": "Budget (tokens)", + "simulate": "Simulate", + "resultsTitle": "{count} result(s)", + "resolutionTitle": "Search resolution", + "resolutionEmbedding": "Embedding", + "resolutionStore": "Vector store", + "resolutionStrategy": "Strategy used", + "rerankApplied": "Rerank applied", + "fallback": "Fallback", + "noResults": "No memories found for this query.", + "tokensUsed": "tokens used", + "none": "none", + "errorFetch": "Failed to fetch preview" + }, + "qdrant": { + "title": "Qdrant (Vector Store Tier 2)", + "description": "Optional Qdrant integration for scalable semantic search", + "enableLabel": "Enable Qdrant", + "enableDesc": "When enabled, Qdrant is used as the primary vector store", + "banner": "Tier 2 vector store — an external, scalable alternative to the built-in sqlite-vec (Tier 1). Enable it only if you have a very large memory set or want shared memory across instances; most users are fine on sqlite-vec. When enabled it becomes the primary store and automatically falls back to sqlite-vec if unreachable.", + "hostHelp": "Local Docker: http://localhost:6333 · Qdrant Cloud: your cluster URL", + "collectionHelp": "Any name — OmniRoute creates it on first use", + "embeddingModelHelp": "Sets the vector dimension automatically on first use. Existing memories are not back-filled, and changing the model after data exists needs a fresh collection.", + "testConnection": "Test connection", + "testing": "Testing...", + "statusActive": "Active", + "statusError": "Error", + "statusDisabled": "Disabled", + "healthOk": "Connection OK ({latencyMs}ms)", + "healthError": "Connection error", + "saved": "Settings saved", + "saveError": "Failed to save", + "portLabel": "Port", + "embeddingModelLabel": "Embedding Model", + "optional": "optional", + "apiKeyKeepPlaceholder": "Leave blank to keep current key", + "apiKeyOptional": "Leave blank if not using authentication", + "removeApiKey": "Remove", + "quickSelectModel": "Quick select", + "searchTestTitle": "Semantic search test", + "searchPlaceholder": "Type a test query...", + "searching": "Searching...", + "search": "Search", + "cleanupTitle": "Clean up old points", + "cleanupDesc": "Remove Qdrant points for expired memories (retention period).", + "cleaning": "Cleaning...", + "cleanNow": "Clean now", + "cleanupSuccess": "{count} point(s) removed", + "cleanupFailed": "Cleanup failed" + }, + "rerank": { + "enableLabel": "Enable Rerank", + "enableDesc": "Reorders results with a reranking model after search", + "warning": "Rerank adds +200-500ms latency and additional cost per request. Use sparingly.", + "providerModelLabel": "Rerank Provider / Model", + "noProviderWithKey": "No provider with configured API key. Configure a provider to use rerank.", + "selectProviderModel": "Select a provider/model" + }, + "saving": "Saving...", + "summarize": { + "title": "Compact old memories", + "noCandidates": "No memories eligible for compaction (criteria: >30 days old).", + "candidatesDesc": "{count} memories will be compacted into summaries. This action cannot be undone.", + "confirm": "Compact now" + }, + "tabs": { + "memories": "Memories", + "playground": "Playground", + "engine": "Engine" + }, + "tooltip": { + "totalEntries": "Total memories stored for this API key", + "tokensUsed": "Estimated total tokens occupied by active memories", + "hitRate": "Read-by-ID cache hit rate (not semantic recall accuracy)", + "factual": "Objective, permanent facts from user context", + "episodic": "Events and experiences from conversation history", + "procedural": "Procedures, workflows, and instructions the assistant should follow", + "semantic": "Concepts, preferences, and domain knowledge" + }, + "memoryEnabled": "Memory enabled" }, "skills": { - "title": "Skills", - "description": "Manage and monitor AI skills", - "skillsTab": "Skills", - "executionsTab": "Executions", - "sandboxTab": "Sandbox", - "loading": "Loading skills...", - "noSkills": "No skills found", - "noExecutions": "No executions found", - "enabled": "Enabled", - "disabled": "Disabled", - "version": "Version", - "tableDescription": "Description", - "skill": "Skill", - "status": "Status", - "duration": "Duration", - "time": "Time", - "sandboxConfig": "Sandbox Configuration", - "cpuLimit": "CPU Limit", - "cpuLimitDesc": "Maximum execution time per skill", - "memoryLimit": "Memory Limit", - "memoryLimitDesc": "Maximum memory allocation", - "timeout": "Timeout", - "timeoutDesc": "Maximum wait time for response", - "networkAccess": "Network Access", - "networkAccessDesc": "Allow outbound network requests", - "mode": "Mode", + "title": "Kỹ năng", + "description": "Quản lý và giám sát các kỹ năng AI", + "skillsTab": "Kỹ năng", + "executionsTab": "Lần thực thi", + "sandboxTab": "Hộp cát", + "loading": "Đang tải các kỹ năng...", + "noSkills": "Không tìm thấy kỹ năng nào", + "noExecutions": "Không tìm thấy lượt thực thi nào", + "enabled": "Đã bật", + "disabled": "Đã tắt", + "version": "Phiên bản", + "tableDescription": "Mô tả", + "skill": "Kỹ năng", + "status": "Trạng thái", + "duration": "Thời lượng", + "time": "Thời gian", + "sandboxConfig": "Cấu hình hộp cát", + "cpuLimit": "Giới hạn CPU", + "cpuLimitDesc": "Thời gian thực thi tối đa cho mỗi kỹ năng", + "memoryLimit": "Giới hạn bộ nhớ", + "memoryLimitDesc": "Dung lượng bộ nhớ cấp phát tối đa", + "timeout": "Thời gian chờ", + "timeoutDesc": "Thời gian chờ tối đa cho phản hồi", + "networkAccess": "Truy cập mạng", + "networkAccessDesc": "Cho phép gửi các yêu cầu mạng ra ngoài", + "mode": "Chế độ", "q": "Q", "filterSkillsPlaceholder": "Lọc kỹ năng theo tên, mô tả hoặc thẻ", "allModes": "Tất cả các chế độ", - "totalSkills": "__MISSING__:Total Skills", - "enabledSkills": "__MISSING__:Enabled", - "totalExecutions": "__MISSING__:Executions", - "successRate": "__MISSING__:Success Rate", - "marketplaceTab": "__MISSING__:Marketplace", - "applyFilters": "__MISSING__:Apply filters", - "popularDefaultsLabel": "__MISSING__:Popular by default for selected provider:", - "onMode": "__MISSING__:ON", - "offMode": "__MISSING__:OFF", - "autoMode": "__MISSING__:AUTO", - "installSkillButton": "__MISSING__:Install Skill", - "installSkillModalTitle": "__MISSING__:Install Skill", - "installJsonPlaceholder": "__MISSING__:Paste skill manifest JSON here...", - "installing": "__MISSING__:Installing...", - "installSuccess": "__MISSING__:Skill installed ({id})", - "installError": "__MISSING__:Install failed", - "invalidJson": "__MISSING__:Invalid JSON", - "searchMarketplacePlaceholder": "__MISSING__:Search skills...", - "searchMarketplace": "__MISSING__:Search Marketplace", - "marketplaceEmpty": "__MISSING__:No skills found in marketplace", - "marketplaceError": "__MISSING__:Search failed", - "installingFromMarketplace": "__MISSING__:Installing from marketplace...", - "popularSkills": "__MISSING__:Popular Skills", - "skillsMarketplace": "Thị trường kỹ năng", - "searching": "__MISSING__:Searching...", - "pageInfo": "__MISSING__:Page {page} of {totalPages} ({total} total)", - "previous": "__MISSING__:Previous", - "next": "__MISSING__:Next", - "activeProvider": "__MISSING__:Active provider:", - "changeInSettings": "__MISSING__:Change this in Settings → Memory & Skills.", - "installs": "__MISSING__:installs", - "marketplaceSkillsMpHint": "__MISSING__:Configure your SkillsMP API key in Settings to browse the marketplace.", - "marketplaceSkillsShHint": "__MISSING__:Search the skills.sh open directory to discover and install agent skills.", - "installSkillModalDesc": "__MISSING__:Paste a skill manifest JSON or upload a .json file.", - "uploadJson": "__MISSING__:Upload JSON", - "cancel": "__MISSING__:Cancel", - "installSkill": "Cài đặt kỹ năng" + "totalSkills": "Tổng số kỹ năng", + "enabledSkills": "Đã bật", + "totalExecutions": "Số lượt thực thi", + "successRate": "Tỷ lệ thành công", + "marketplaceTab": "Chợ kỹ năng", + "applyFilters": "Áp dụng bộ lọc", + "popularDefaultsLabel": "Phổ biến theo mặc định cho nhà cung cấp đã chọn:", + "onMode": "BẬT", + "offMode": "TẮT", + "autoMode": "TỰ ĐỘNG", + "installSkillButton": "Cài đặt kỹ năng", + "installSkillModalTitle": "Cài đặt kỹ năng", + "installJsonPlaceholder": "Dán tệp kê khai JSON của kỹ năng vào đây...", + "installing": "Đang cài đặt...", + "installSuccess": "Đã cài đặt kỹ năng ({id})", + "installError": "Cài đặt thất bại", + "invalidJson": "JSON không hợp lệ", + "searchMarketplacePlaceholder": "Tìm kiếm kỹ năng...", + "searchMarketplace": "Tìm kiếm chợ kỹ năng", + "marketplaceEmpty": "Không tìm thấy kỹ năng nào trong chợ kỹ năng", + "marketplaceError": "Tìm kiếm thất bại", + "installingFromMarketplace": "Đang cài đặt từ chợ kỹ năng...", + "popularSkills": "Kỹ năng phổ biến", + "skillsMarketplace": "Chợ kỹ năng", + "searching": "Đang tìm kiếm...", + "pageInfo": "Trang {page} trên {totalPages} (tổng cộng {total})", + "previous": "Trước", + "next": "Tiếp theo", + "activeProvider": "Nhà cung cấp đang hoạt động:", + "changeInSettings": "Thay đổi mục này trong Cài đặt → Bộ nhớ & Kỹ năng.", + "installs": "lượt cài đặt", + "marketplaceSkillsMpHint": "Cấu hình khóa API SkillsMP trong Cài đặt để duyệt chợ kỹ năng.", + "marketplaceSkillsShHint": "Tìm kiếm thư mục mở skills.sh để khám phá và cài đặt các kỹ năng của tác nhân.", + "installSkillModalDesc": "Dán tệp kê khai JSON của kỹ năng hoặc tải tệp .json lên.", + "uploadJson": "Tải JSON lên", + "cancel": "Hủy", + "installSkill": "Cài đặt kỹ năng", + "delete": "Delete" }, "health": { - "title": "Tình trạng hệ thống", - "description": "Giám sát thời gian thực phiên bản OmniRoute của bạn", - "healthy": "khỏe mạnh", - "degraded": "xuống cấp", - "down": "xuống", + "title": "Trạng thái hệ thống", + "description": "Giám sát theo thời gian thực bản triển khai OmniRoute của bạn", + "healthy": "Hoạt động tốt", + "degraded": "Suy giảm", + "down": "Ngừng hoạt động", "uptime": "Thời gian hoạt động", "memory": "Bộ nhớ", "memoryRss": "Bộ nhớ (RSS)", - "heap": "Đống", + "heap": "Heap", "cpu": "CPU", "database": "Cơ sở dữ liệu", "version": "Phiên bản", "lastCheck": "Kiểm tra lần cuối", - "providerHealth": "Sức khỏe nhà cung cấp", - "systemMetrics": "Số liệu hệ thống", - "tokenHealth": "Tình trạng mã thông báo", + "providerHealth": "Trạng thái nhà cung cấp", + "systemMetrics": "Chỉ số hệ thống", + "tokenHealth": "Tình trạng token", "refreshAll": "Làm mới tất cả", "checkNow": "Kiểm tra ngay", - "loadingHealth": "Đang tải dữ liệu sức khỏe...", - "failedToLoad": "Không tải được dữ liệu sức khỏe: {error}", + "loadingHealth": "Đang tải dữ liệu trạng thái...", + "failedToLoad": "Không thể tải dữ liệu trạng thái: {error}", "retry": "Thử lại", - "allOperational": "Tất cả các hệ thống hoạt động", - "issuesDetected": "Đã phát hiện sự cố hệ thống", + "allOperational": "Tất cả hệ thống đang hoạt động bình thường", + "issuesDetected": "Phát hiện sự cố hệ thống", "updatedAt": "Đã cập nhật {time}", "latency": "Độ trễ", "latencyP50": "p50", @@ -3332,254 +3657,265 @@ "notAvailable": "—", "totalRequests": "Tổng số yêu cầu", "noDataYet": "Chưa có dữ liệu", - "promptCache": "Bộ nhớ đệm nhắc nhở", - "entries": "Bài dự thi", - "hitRate": "Tỷ lệ trúng", - "hitsMisses": "Lượt truy cập / Bỏ lỡ", - "signatureCache": "Bộ đệm chữ ký", + "promptCache": "Prompt Cache", + "entries": "Bản ghi", + "hitRate": "Tỷ lệ hit", + "hitsMisses": "Hit / Miss", + "signatureCache": "Signature Cache", "signatureDefaults": "Mặc định", "signatureTool": "Công cụ", - "signatureFamily": "gia đình", + "signatureFamily": "Họ", "signatureSession": "Phiên", "recovering": "Đang phục hồi", - "noCBData": "Không có dữ liệu ngắt mạch có sẵn. Thực hiện một số yêu cầu đầu tiên.", - "providerHealthStatusAria": "Tình trạng sức khỏe của nhà cung cấp", - "issuesLabel": "Đã phát hiện sự cố", - "operational": "hoạt động", + "noCBData": "Không có dữ liệu bộ ngắt mạch. Vui lòng thực hiện một vài yêu cầu trước.", + "providerHealthStatusAria": "Trạng thái hoạt động của nhà cung cấp", + "issuesLabel": "Phát hiện sự cố", + "operational": "Đang hoạt động", "providers": "Nhà cung cấp", - "configuredProvidersLabel": "Được định cấu hình trong bảng điều khiển", - "configuredProvidersHint": "Nhà cung cấp có thông tin xác thực được lưu trong /dashboard/providers, bất kể trạng thái thời gian chạy.", - "activeProviders": "{count} active", - "activeProvidersHint": "Nhà cung cấp được định cấu hình hiện đã được bật cho các yêu cầu định tuyến.", - "monitoredProviders": "{count} monitored", - "monitoredProvidersHint": "Các nhà cung cấp hiện được theo dõi bởi máy theo dõi tình trạng ngắt mạch.", - "healthyCount": "{count} khỏe mạnh", - "nodeVersion": "Nút {version}", - "failures": "{count} thất bại", - "failuresPlural": "{count} thất bại", - "lastFailure": "Cuối cùng", - "rateLimitStatus": "Trạng thái giới hạn tỷ lệ", - "activeLimiters": "{count} bộ giới hạn hoạt động", - "activeLimitersPlural": "{count} bộ giới hạn hoạt động", + "configuredProvidersLabel": "Được cấu hình trong bảng điều khiển", + "configuredProvidersHint": "Các nhà cung cấp có thông tin xác thực được lưu trong /dashboard/providers, bất kể trạng thái thời gian chạy.", + "activeProviders": "{count} đang hoạt động", + "activeProvidersHint": "Các nhà cung cấp được cấu hình hiện đang được bật để định tuyến yêu cầu.", + "monitoredProviders": "{count} được giám sát", + "monitoredProvidersHint": "Các nhà cung cấp hiện đang được theo dõi bởi bộ giám sát tình trạng của bộ ngắt mạch.", + "healthyCount": "{count} hoạt động bình thường", + "nodeVersion": "Node {version}", + "failures": "{count} lần thất bại", + "failuresPlural": "{count} lần thất bại", + "lastFailure": "Gần nhất", + "rateLimitStatus": "Trạng thái giới hạn tần suất", + "activeLimiters": "{count} bộ giới hạn đang hoạt động", + "activeLimitersPlural": "{count} bộ giới hạn đang hoạt động", "queued": "Đã xếp hàng", "queuedCount": "{count} đã xếp hàng", "running": "đang chạy", "runningCount": "{count} đang chạy", - "ok": "được rồi", - "activeLockouts": "Khóa hoạt động", - "resetConfirm": "Đặt lại tất cả các bộ ngắt mạch về trạng thái khỏe mạnh? Điều này sẽ xóa tất cả số lần lỗi và khôi phục tất cả các nhà cung cấp về trạng thái hoạt động.", - "resetAllTitle": "Đặt lại tất cả các bộ ngắt mạch về trạng thái khỏe mạnh", + "ok": "OK", + "activeLockouts": "Các trạng thái khóa đang hoạt động", + "resetConfirm": "Đặt lại tất cả bộ ngắt mạch về trạng thái hoạt động bình thường? Thao tác này sẽ xóa tất cả số lần thất bại và khôi phục tất cả nhà cung cấp về trạng thái hoạt động.", + "resetAllTitle": "Đặt lại tất cả bộ ngắt mạch về trạng thái hoạt động bình thường", "resetting": "Đang đặt lại...", "resetAll": "Đặt lại tất cả", - "until": "Cho đến {time}", - "limitExhausted": "Exhausted", - "learnedFromHeaders": "Learned from headers", - "remainingOfLimit": "{remaining}/{limit} remaining", - "throttleStatus": "Throttle: {value}", - "lastHeaderUpdate": "Header update: {age}", + "until": "Đến {time}", + "limitExhausted": "Đã dùng hết", + "learnedFromHeaders": "Được suy ra từ header", + "remainingOfLimit": "Còn lại {remaining}/{limit}", + "throttleStatus": "Điều tiết: {value}", + "lastHeaderUpdate": "Cập nhật header: {age}", "databaseHealth": "Tình trạng cơ sở dữ liệu", - "stickyBoundSessions": "Phiên bị ràng buộc", + "stickyBoundSessions": "Các phiên liên kết cố định", "sessionsByApiKey": "Phiên theo khóa API", "noActiveSessionsTracked": "Chưa có phiên hoạt động nào được theo dõi.", - "noSessionQuotaMonitorsActive": "Không có màn hình hạn ngạch phiên nào đang hoạt động.", - "gracefulDegradationStatus": "Tình trạng xuống cấp duyên dáng", + "noSessionQuotaMonitorsActive": "Không có trình giám sát hạn ngạch phiên nào đang hoạt động.", + "gracefulDegradationStatus": "Trạng thái suy giảm có kiểm soát", "additionalModels": "+{count} mô hình khác", - "providerHealthMatrixTitle": "__MISSING__:Provider Health Matrix", - "providerHealthMatrixDescription": "__MISSING__:Provider × account × model states from breakers, cooldowns, lockouts and logs.", - "healthMatrixRange": "__MISSING__:Health matrix range", - "providerFilter": "__MISSING__:Provider filter", - "onlyIssues": "__MISSING__:Only issues", - "refresh": "__MISSING__:Refresh", - "accounts": "__MISSING__:Accounts", - "models": "__MISSING__:Models", - "issues": "__MISSING__:Issues", - "loadingProviderHealthMatrix": "__MISSING__:Loading provider health matrix...", - "failedProviderHealthMatrix": "__MISSING__:Failed to load Provider Health Matrix: {error}", - "noProvidersMatchedFilters": "__MISSING__:No providers matched the current filters.", - "modelPillSummary": "__MISSING__:{requests} req · {successRate} success · {latency} avg", - "modelLockoutSummary": "__MISSING__:{reason} · {duration} left", - "locked": "__MISSING__:locked", - "inferred": "__MISSING__:inferred", - "inactive": "__MISSING__:Inactive", - "noConnectionId": "__MISSING__:no connection id", - "accountModelSummary": "__MISSING__:{connectionId} · {count} models", - "cooldown": "__MISSING__:cooldown", - "durationRemaining": "__MISSING__:{duration} remaining", - "noSyncedModelsOrTraffic": "__MISSING__:No synced models or recent traffic yet.", - "providerRowSummary": "__MISSING__:{active}/{total} active accounts · {requests} req · {successRate} success · {latency} avg", - "cooldownCount": "__MISSING__:{count} cooldown", - "lockoutCount": "__MISSING__:{count} lockouts", - "issueCount": "__MISSING__:{count} issues", - "score": "__MISSING__:Score", - "lastRequest": "__MISSING__:Last request", - "lastError": "__MISSING__:Last error" + "providerHealthMatrixTitle": "Ma trận tình trạng nhà cung cấp", + "providerHealthMatrixDescription": "Trạng thái của nhà cung cấp × tài khoản × mô hình từ bộ ngắt mạch, thời gian chờ, trạng thái khóa và nhật ký.", + "healthMatrixRange": "Phạm vi ma trận tình trạng", + "providerFilter": "Bộ lọc nhà cung cấp", + "onlyIssues": "Chỉ sự cố", + "refresh": "Làm mới", + "accounts": "Tài khoản", + "models": "Mô hình", + "issues": "Sự cố", + "loadingProviderHealthMatrix": "Đang tải ma trận tình trạng nhà cung cấp...", + "failedProviderHealthMatrix": "Không thể tải ma trận tình trạng nhà cung cấp: {error}", + "noProvidersMatchedFilters": "Không có nhà cung cấp nào khớp với bộ lọc hiện tại.", + "modelPillSummary": "{requests} yêu cầu · {successRate} thành công · {latency} trung bình", + "modelLockoutSummary": "{reason} · còn lại {duration}", + "locked": "bị khóa", + "inferred": "được suy luận", + "inactive": "Không hoạt động", + "noConnectionId": "không có ID kết nối", + "accountModelSummary": "{connectionId} · {count} mô hình", + "cooldown": "thời gian chờ", + "durationRemaining": "còn lại {duration}", + "noSyncedModelsOrTraffic": "Chưa có mô hình được đồng bộ hóa hoặc lưu lượng truy cập gần đây.", + "providerRowSummary": "{active}/{total} tài khoản hoạt động · {requests} yêu cầu · {successRate} thành công · {latency} trung bình", + "cooldownCount": "{count} thời gian chờ", + "lockoutCount": "{count} lượt khóa", + "issueCount": "{count} sự cố", + "score": "Điểm số", + "lastRequest": "Yêu cầu gần nhất", + "lastError": "Lỗi gần nhất" }, "telemetry": { - "title": "Đo từ xa hệ thống", - "description": "Các tín hiệu yêu cầu, thời gian chạy, phiên và bộ nhớ luân phiên từ quy trình OmniRoute này.", + "title": "Dữ liệu đo từ xa của hệ thống", + "description": "Các tín hiệu thu thập liên tục về yêu cầu, thời gian chạy, phiên và bộ nhớ từ quy trình OmniRoute này.", "uptime": "Thời gian hoạt động", "totalRequests": "Tổng số yêu cầu", "avgLatency": "Độ trễ trung bình", "errorRate": "Tỷ lệ lỗi", "activeConnections": "Kết nối đang hoạt động", - "memoryUsage": "Sử dụng bộ nhớ", + "memoryUsage": "Mức sử dụng bộ nhớ", "latencyTrend": "Xu hướng độ trễ", "throughputTrend": "Xu hướng thông lượng", - "memoryTrend": "Xu hướng trí nhớ", + "memoryTrend": "Xu hướng bộ nhớ", "refresh": "Làm mới", "updatedAt": "Đã cập nhật {time}", "loadFailed": "Không thể tải dữ liệu đo từ xa.", - "partialData": "Đo từ xa khả dụng một phần: {error}" + "partialData": "Dữ liệu đo từ xa khả dụng một phần: {error}" }, "mitm": { - "title": "Ủy quyền MITM", - "description": "Proxy minh bạch để chặn và định tuyến các yêu cầu của khách hàng.", - "enable": "Kích hoạt proxy MITM", + "title": "Proxy MITM", + "description": "Proxy trong suốt để chặn và định tuyến các yêu cầu của máy khách.", + "enable": "Kích hoạt Proxy MITM", "enableDesc": "Bắt đầu hoặc dừng quá trình chặn cục bộ và ghi đè DNS.", "status": "Trạng thái", "running": "Đang chạy", "stopped": "Đã dừng", "start": "Bắt đầu", - "stop": "Dừng lại", + "stop": "Dừng", "refresh": "Làm mới", - "port": "Cổng ủy quyền", - "apiKey": "Khóa API bộ định tuyến", - "apiKeyPlaceholder": "Tùy chọn; quay trở lại khóa cục bộ", - "sudoPassword": "Mật khẩu Sudo", - "cachedPassword": "Được lưu vào bộ nhớ đệm cho quá trình này", + "port": "Cổng proxy", + "apiKey": "Khóa API của bộ định tuyến", + "apiKeyPlaceholder": "Không bắt buộc; sử dụng khóa cục bộ dự phòng", + "sudoPassword": "Mật khẩu sudo", + "cachedPassword": "Được lưu cache cho quy trình này", "saveSettings": "Lưu cài đặt", "settingsSaved": "Đã lưu cài đặt MITM.", - "startedSuccess": "Proxy MITM đã bắt đầu.", + "startedSuccess": "Proxy MITM đã khởi động.", "stoppedSuccess": "Proxy MITM đã dừng.", "saveFailed": "Không thể cập nhật cài đặt MITM.", "loadFailed": "Không thể tải cài đặt MITM.", - "invalidPort": "Việc chặn MITM trong suốt hiện yêu cầu cổng 443.", + "invalidPort": "Tính năng chặn MITM trong suốt hiện yêu cầu cổng 443.", "certificate": "Chứng chỉ CA", - "certificateReady": "Chứng chỉ có sẵn để cài đặt tin cậy của khách hàng.", + "certificateReady": "Chứng chỉ đã sẵn sàng để cài đặt tin cậy trên máy khách.", "certificateMissing": "Chứng chỉ chưa được tạo.", - "available": "Có sẵn", + "available": "Khả dụng", "missing": "Thiếu", "downloadCert": "Tải xuống chứng chỉ CA", "regenerateCert": "Tạo lại chứng chỉ", - "regenerateConfirm": "Điều này sẽ làm mất hiệu lực niềm tin của khách hàng hiện tại. Tiếp tục?", - "regenerateSuccess": "Chứng chỉ MITM đã được tạo lại.", + "regenerateConfirm": "Thao tác này sẽ làm mất hiệu lực tin cậy hiện tại của client. Tiếp tục?", + "regenerateSuccess": "Đã tạo lại chứng chỉ MITM.", "regenerateFailed": "Không thể tạo lại chứng chỉ MITM.", - "targetRoutes": "Tuyến đường mục tiêu", - "interceptedRequests": "Yêu cầu bị chặn", + "targetRoutes": "Tuyến mục tiêu", + "interceptedRequests": "Yêu cầu đã chặn", "activeConnections": "Kết nối đang hoạt động", - "dnsConfigured": "Đã định cấu hình DNS", + "dnsConfigured": "Đã cấu hình DNS", "pid": "PID", - "lastIntercept": "Đánh chặn cuối cùng", + "lastIntercept": "Lần chặn cuối cùng", "target": "Mục tiêu", - "host": "Máy chủ", - "localPort": "Cảng địa phương", - "endpoints": "Điểm cuối", + "host": "Host", + "localPort": "Cổng cục bộ", + "endpoints": "Các endpoint", "enabled": "Đã bật", - "configured": "Đã định cấu hình", + "configured": "Đã cấu hình", "yes": "Có", "no": "Không", - "noTargets": "Không có tuyến đường mục tiêu nào được định cấu hình." + "noTargets": "Chưa cấu hình tuyến mục tiêu nào." }, "limits": { - "title": "Giới hạn & hạn ngạch", - "rateLimit": "Giới hạn tỷ lệ", + "title": "Giới hạn & Hạn ngạch", + "rateLimit": "Giới hạn tốc độ", "remaining": "Còn lại", "requestsPerMinute": "Yêu cầu/phút", - "tokensPerMinute": "Mã thông báo/phút", + "tokensPerMinute": "Token/phút", "dailyLimit": "Giới hạn hàng ngày" }, "logs": { "title": "Nhật ký", "requestLogs": "Nhật ký yêu cầu", "proxyLogs": "Nhật ký proxy", - "auditLog": "Nhật ký kiểm tra", + "auditLog": "Nhật ký kiểm toán", "console": "Bảng điều khiển", - "auditLogDesc": "Hành động hành chính và sự kiện bảo mật", + "auditLogDesc": "Các hoạt động quản trị và sự kiện bảo mật", "loading": "Đang tải...", "refresh": "Làm mới", "filterByAction": "Lọc theo hành động...", - "filterByActor": "Lọc theo diễn viên...", - "filterEntriesAria": "Lọc các mục nhật ký kiểm tra", + "filterByActor": "Lọc theo tác nhân...", + "filterEntriesAria": "Lọc các mục nhật ký kiểm toán", "filterByActionTypeAria": "Lọc theo loại hành động", - "filterByActorAria": "Lọc theo diễn viên", - "refreshAuditLogAria": "Làm mới nhật ký kiểm tra", - "tableAria": "Mục nhật ký kiểm tra", - "failedFetchAuditLog": "Không tìm nạp được nhật ký kiểm tra", - "showing": "Hiển thị các mục {count} (bù đắp {offset})", + "filterByActorAria": "Lọc theo tác nhân", + "refreshAuditLogAria": "Làm mới nhật ký kiểm toán", + "tableAria": "Các mục nhật ký kiểm toán", + "failedFetchAuditLog": "Không thể tải nhật ký kiểm toán", + "showing": "Hiển thị {count} mục (độ lệch {offset})", "search": "Tìm kiếm", - "timestamp": "Dấu thời gian", - "action": "hành động", - "actor": "diễn viên", - "target": "Mục tiêu", + "timestamp": "Mốc thời gian", + "action": "Hành động", + "actor": "Người thực hiện", + "target": "Đối tượng", "details": "Chi tiết", "ipAddress": "Địa chỉ IP", "notAvailable": "—", - "noEntries": "Không tìm thấy mục nhật ký kiểm tra nào", - "previous": "trước đó", + "noEntries": "Không tìm thấy mục nhật ký kiểm toán nào", + "previous": "Trước", "next": "Tiếp theo", - "providerWarningTitle": "Provider Warning Title", - "viewDetails": "View Details", - "eventMetadata": "Event Metadata", - "eventPayload": "Event Payload", - "requestId": "Request Id", - "providerWarningDesc": "Provider Warning Desc", + "providerWarningTitle": "Cảnh báo từ nhà cung cấp", + "viewDetails": "Xem chi tiết", + "eventMetadata": "Siêu dữ liệu sự kiện", + "eventPayload": "Payload sự kiện", + "requestId": "ID yêu cầu", + "providerWarningDesc": "Một số nhà cung cấp đã trả về cảnh báo trong quá trình xử lý yêu cầu", "a": "A", "offset": "Offset", - "limit": "Limit", - "status": "Status", - "resourceType": "Resource Type", - "totalEntries": "Total Entries", + "limit": "Giới hạn", + "status": "Trạng thái", + "resourceType": "Loại tài nguyên", + "totalEntries": "Tổng số mục", "tab": "Tab", - "auditModalSubtitle": "Audit Modal Subtitle", - "close": "Close", - "runningRequests": "Active Requests", - "runningRequestsDesc": "Real-time view of currently running upstream requests", + "auditModalSubtitle": "Chi tiết sự kiện và siêu dữ liệu", + "close": "Đóng", + "runningRequests": "Yêu cầu đang hoạt động", + "runningRequestsDesc": "Xem theo thời gian thực các yêu cầu thượng nguồn hiện đang chạy", "clearAll": "Xóa tất cả", "confirmClearActiveRequests": "Xóa tất cả yêu cầu đang hoạt động?", - "model": "Model", - "provider": "Provider", - "account": "Account", - "elapsed": "Elapsed", - "activeStage": "__MISSING__:Stage", - "activeStageUnknown": "__MISSING__:Not sent to upstream yet", - "activeStageRegistered": "__MISSING__:Registered", - "activeStagePayloadPrepared": "__MISSING__:Payload prepared", - "activeStageWaitingAccountSlot": "__MISSING__:Waiting for account slot", - "activeStageWaitingRateLimit": "__MISSING__:Waiting for rate limiter", - "activeStageRateLimitSlotAcquired": "__MISSING__:Rate limit slot acquired", - "activeStageSendingToProvider": "__MISSING__:Sending to upstream", - "activeStageProviderResponseStarted": "__MISSING__:Upstream response started", - "count": "Count", + "model": "Mô hình", + "provider": "Nhà cung cấp", + "account": "Tài khoản", + "elapsed": "Thời gian đã trôi qua", + "activeStage": "Giai đoạn", + "activeStageUnknown": "Chưa gửi đến hệ thống thượng nguồn", + "activeStageRegistered": "Đã đăng ký", + "activeStagePayloadPrepared": "Đã chuẩn bị payload", + "activeStageWaitingAccountSlot": "Đang chờ suất tài khoản", + "activeStageWaitingRateLimit": "Đang chờ bộ giới hạn tốc độ", + "activeStageRateLimitSlotAcquired": "Đã nhận được suất giới hạn tốc độ", + "activeStageSendingToProvider": "Đang gửi đến hệ thống thượng nguồn", + "activeStageProviderResponseStarted": "Đã bắt đầu nhận phản hồi từ hệ thống thượng nguồn", + "count": "Số lượng", "payloads": "Payloads", - "viewPayloads": "View", - "activeCount": "{count} active", - "clientPayload": "Client Request Payload", - "upstreamPayload": "Upstream Provider Payload", - "upstreamNotSentYet": "Not sent to upstream yet", - "runningRequestDetailMeta": "Account: {account} — Elapsed: {elapsed}", - "export": "Export", - "exporting": "Exporting...", - "exportFailed": "Export failed", - "timeRange": "Time Range", - "lastNHours": "Last {hours}", - "defaultRange": "default", + "viewPayloads": "Xem", + "activeCount": "{count} đang hoạt động", + "clientPayload": "Payload yêu cầu của máy khách", + "upstreamPayload": "Payload của nhà cung cấp thượng nguồn", + "upstreamNotSentYet": "Chưa được gửi đến hệ thống thượng nguồn", + "runningRequestDetailMeta": "Tài khoản: {account} — Thời gian trôi qua: {elapsed}", + "export": "Xuất", + "exporting": "Đang xuất...", + "exportFailed": "Xuất thất bại", + "timeRange": "Khoảng thời gian", + "lastNHours": "{hours} gần đây", + "defaultRange": "mặc định", "consoleViewer": { - "fetchFailed": "Failed to fetch logs", - "copyFailed": "Failed to copy log entry", - "copyLogEntry": "Copy log entry" - } + "fetchFailed": "Không thể tải nhật ký", + "copyFailed": "Không thể sao chép mục nhật ký", + "copyLogEntry": "Sao chép mục nhật ký" + }, + "cleanHistoryButton": "Clean history", + "cleanHistoryTitle": "Clean log history?", + "cleanHistoryMessage": "This permanently clears all request log rows, legacy detail rows, and local artifact files under DATA_DIR/call_logs. The live page will refresh after cleanup.", + "cleanHistoryConfirm": "Clean history", + "cleanHistoryCancel": "Cancel", + "cleanHistorySuccess": "Cleaned {deleted} log entries, {deletedArtifacts} artifacts, and {deletedDetailedLogs} legacy detail rows.", + "cleanHistoryEmpty": "No request log history was found.", + "cleanHistoryFailed": "Failed to clean log history.", + "compressionLogTitle": "Compression Log", + "compressionLogEmpty": "No compressed requests yet. Compression stats will appear here when requests are processed with compression enabled.", + "tokens": "tokens" }, "onboarding": { "welcome": "Chào mừng", "security": "Bảo mật", - "test": "kiểm tra", + "test": "Kiểm tra", "ready": "Sẵn sàng!", "setPassword": "Đặt mật khẩu", "addProvider": "Thêm nhà cung cấp đầu tiên của bạn", "getStarted": "Bắt đầu", "skip": "Bỏ qua", "skipWizard": "Bỏ qua hoàn toàn trình hướng dẫn", - "skipPassword": "Bỏ qua việc thiết lập mật khẩu", + "skipPassword": "Bỏ qua thiết lập mật khẩu", "skipAndContinue": "Bỏ qua & Tiếp tục", "passwordLabel": "Mật khẩu", "confirmPassword": "Xác nhận mật khẩu", @@ -3588,47 +3924,50 @@ "passwordsMismatch": "Mật khẩu không khớp", "setupComplete": "Thiết lập hoàn tất!", "goToDashboard": "Đi tới Bảng điều khiển →", - "welcomeDesc": "OmniRoute là proxy API AI cục bộ của bạn. Nó định tuyến các yêu cầu đến nhiều nhà cung cấp AI với tính năng cân bằng tải, chuyển đổi dự phòng và theo dõi việc sử dụng.", + "welcomeDesc": "OmniRoute là proxy API AI cục bộ của bạn. Nó định tuyến các yêu cầu đến nhiều nhà cung cấp AI với tính năng cân bằng tải, chuyển đổi dự phòng và theo dõi mức sử dụng.", "multiProvider": "Đa nhà cung cấp", - "usageTracking": "Theo dõi sử dụng", - "securityDesc": "Đặt mật khẩu để bảo vệ trang tổng quan của bạn hoặc bỏ qua ngay bây giờ.", - "providerDesc": "Kết nối nhà cung cấp AI đầu tiên của bạn. Bạn có thể thêm nhiều hơn sau.", + "usageTracking": "Theo dõi mức sử dụng", + "securityDesc": "Đặt mật khẩu để bảo vệ bảng điều khiển của bạn, hoặc bỏ qua lúc này.", + "providerDesc": "Kết nối nhà cung cấp AI đầu tiên của bạn. Bạn có thể thêm nhiều nhà cung cấp khác sau.", "apiKeyRequired": "Khóa API (bắt buộc)", "customUrlOptional": "URL tùy chỉnh (tùy chọn)", - "testDesc": "Hãy xác minh kết nối nhà cung cấp của bạn hoạt động.", + "testDesc": "Hãy xác minh xem kết nối với nhà cung cấp của bạn có hoạt động không.", "runTest": "Chạy kiểm tra kết nối", "testingConnection": "Đang kiểm tra kết nối...", "connectionSuccessful": "Kết nối thành công! Nhà cung cấp của bạn đã sẵn sàng.", - "noProviderFound": "Không tìm thấy nhà cung cấp nào. Bạn có thể thêm một từ bảng điều khiển sau.", - "testFailed": "Thử nghiệm không thành công nhưng bạn có thể định cấu hình điều này sau.", - "couldNotTest": "Không thể kiểm tra ngay bây giờ. Bạn có thể kiểm tra từ bảng điều khiển.", - "doneDesc": "Bạn đã hoàn tất! Phiên bản OmniRoute của bạn đã được định cấu hình và sẵn sàng thực hiện các yêu cầu AI proxy.", - "yourEndpoint": "Điểm cuối của bạn:", + "noProviderFound": "Không tìm thấy nhà cung cấp nào. Bạn có thể thêm sau từ bảng điều khiển.", + "testFailed": "Kiểm tra thất bại, nhưng bạn có thể cấu hình sau.", + "couldNotTest": "Không thể kiểm tra lúc này. Bạn có thể kiểm tra từ bảng điều khiển.", + "doneDesc": "Bạn đã hoàn tất! Phiên bản OmniRoute của bạn đã được cấu hình và sẵn sàng làm proxy cho các yêu cầu AI.", + "yourEndpoint": "Endpoint của bạn:", "continue": "Tiếp tục", "retry": "Thử lại", - "failedSetPassword": "Không thể đặt mật khẩu. Hãy thử lại.", - "failedAddProvider": "Không thể thêm nhà cung cấp. Hãy thử lại.", + "failedSetPassword": "Đặt mật khẩu thất bại. Hãy thử lại.", + "failedAddProvider": "Thêm nhà cung cấp thất bại. Hãy thử lại.", "connectionError": "Lỗi kết nối. Vui lòng thử lại.", - "provider": "nhà cung cấp", - "apiKeyHelp": "Khóa API là mật khẩu cho các dịch vụ AI. Nhận một cái từ trang web của nhà cung cấp của bạn (ví dụ: platform.openai.com, console.anthropic.com).", + "provider": "Nhà cung cấp", + "apiKeyHelp": "Khóa API là mật khẩu cho các dịch vụ AI. Hãy lấy một khóa từ trang web của nhà cung cấp của bạn (ví dụ: platform.openai.com, console.anthropic.com).", "tier": { - "subtitle": "OmniRoute tổ chức các nhà cung cấp thành ba cấp để việc định tuyến ưu tiên đường đi đáng tin cậy nhất, chi phí thấp nhất trước tiên.", + "subtitle": "OmniRoute sắp xếp các nhà cung cấp thành ba cấp để việc định tuyến ưu tiên tuyến đáng tin cậy nhất và có chi phí thấp nhất.", "tier1": { - "label": "Khách hàng cao cấp", - "description": "CLI hạng nhất với các luồng xác thực gốc và mô hình lý luận." + "label": "Ứng dụng khách cao cấp", + "description": "Các CLI hàng đầu với luồng xác thực tích hợp sẵn và các mô hình suy luận." }, "tier2": { "label": "Tối ưu hóa chi phí", - "description": "Nhà cung cấp giá rẻ, thông lượng cao được sử dụng cho lưu lượng truy cập hàng ngày." + "description": "Các nhà cung cấp giá rẻ, thông lượng cao được sử dụng cho lưu lượng truy cập hàng ngày." }, "tier3": { - "label": "Dự phòng & đặc sản", - "description": "Các điểm cuối đặc biệt hoặc được lưu trữ cục bộ được sử dụng làm phương án dự phòng." + "label": "Dự phòng & chuyên biệt", + "description": "Các endpoint được lưu trữ cục bộ hoặc chuyên biệt được sử dụng làm phương án dự phòng." }, - "configure": "Định cấu hình nhà cung cấp" + "configure": "Cấu hình nhà cung cấp", + "flowCaption": "Requests flow through your subscription quotas first, then pay-per-token cheap providers, then free-tier providers — automatic, zero-config.", + "afterSetup": "after setup." }, - "tierFlowDiagramAlt": "Sơ đồ dự phòng 3 tầng OmniRoute", - "apiKeyMgmt": "Quản lý khóa API" + "tierFlowDiagramAlt": "Sơ đồ dự phòng 3 cấp của OmniRoute", + "apiKeyMgmt": "Quản lý khóa API", + "tiers": "Tiers" }, "providers": { "title": "Nhà cung cấp", @@ -3637,22 +3976,22 @@ "showFreeOnly": "Chỉ miễn phí", "addProvider": "Thêm nhà cung cấp", "addFirstProvider": "Thêm nhà cung cấp đầu tiên của bạn", - "addFirstProviderDesc": "Kết nối nhà cung cấp AI để bắt đầu định tuyến các yêu cầu thông qua OmniRoute. Bạn có thể sử dụng nhà cung cấp miễn phí, khóa API hoặc tài khoản OAuth.", + "addFirstProviderDesc": "Kết nối một nhà cung cấp AI để bắt đầu định tuyến các yêu cầu thông qua OmniRoute. Bạn có thể sử dụng các nhà cung cấp miễn phí, khóa API hoặc tài khoản OAuth.", "learnMore": "Tìm hiểu thêm", "editProvider": "Chỉnh sửa nhà cung cấp", "deleteProvider": "Xóa nhà cung cấp", - "noProviders": "Không có nhà cung cấp nào được định cấu hình", - "modelAvailability": "Mẫu sẵn có", + "noProviders": "Chưa cấu hình nhà cung cấp nào", + "modelAvailability": "Trạng thái khả dụng của mô hình", "accounts": "Tài khoản", "newAccount": "Tài khoản mới", "deleteConfirm": "Bạn có chắc chắn muốn xóa nhà cung cấp này không?", - "testing": "Đang thử nghiệm...", + "testing": "Đang kiểm tra...", "testConnection": "Kiểm tra kết nối", "testSuccess": "Kết nối thành công", - "testFailed": "Kết nối không thành công", - "available": "Có sẵn", - "cooldown": "Thời gian hồi chiêu", - "unavailable": "Không có sẵn", + "testFailed": "Kết nối thất bại", + "available": "Khả dụng", + "cooldown": "Thời gian chờ", + "unavailable": "Không khả dụng", "unknown": "Không xác định", "oauthLabel": "OAuth", "compatibleLabel": "Tương thích", @@ -3661,59 +4000,59 @@ "messages": "Tin nhắn", "oauthProviders": "Nhà cung cấp OAuth", "freeProviders": "Nhà cung cấp miễn phí", - "apiKeyProviders": "Nhà cung cấp khóa API", - "compatibleProviders": "Nhà cung cấp tương thích với khóa API", + "apiKeyProviders": "Nhà cung cấp API Key", + "compatibleProviders": "Nhà cung cấp tương thích API Key", "testAll": "Kiểm tra tất cả", "reorderByAvailability": "Sắp xếp lại", "reorderByAvailabilityTitle": "Sắp xếp lại các kết nối theo tình trạng khả dụng", "reorderByAvailabilityError": "Không thể sắp xếp lại các kết nối theo tình trạng khả dụng", - "testAllOAuth": "Kiểm tra tất cả các kết nối OAuth", - "testAllFree": "Kiểm tra tất cả các kết nối miễn phí", - "testAllApiKey": "Kiểm tra tất cả các kết nối Khóa API", - "testAllCompatible": "Kiểm tra tất cả các kết nối tương thích", - "connected": "{count} Đã kết nối", + "testAllOAuth": "Kiểm tra tất cả kết nối OAuth", + "testAllFree": "Kiểm tra tất cả kết nối miễn phí", + "testAllApiKey": "Kiểm tra tất cả kết nối API Key", + "testAllCompatible": "Kiểm tra tất cả kết nối tương thích", + "connected": "{count} đã kết nối", "errorCount": "{count} Lỗi ({code})", "errorCountNoCode": "{count} Lỗi", "warningCount": "{count} Cảnh báo", "noConnections": "Không có kết nối", - "expiredBadge": "Expired", - "expiringSoonBadge": "Expiring Soon", - "freeTier": "Bậc miễn phí", - "freeTierAvailable": "Cấp miễn phí có sẵn", - "hasFreeTooltip": "__MISSING__:Free tier available", - "noAuthLabel": "__MISSING__:No Auth", - "noAuthProviders": "__MISSING__:No Auth Providers", - "upstreamProxyLabel": "__MISSING__:Upstream Proxy", - "freeAggregated": "__MISSING__:All providers with free tier (also shown in their native category)", - "deprecated": "Không được dùng nữa", - "deprecatedProvider": "Nhà cung cấp này đã không còn được dùng nữa", + "expiredBadge": "Đã hết hạn", + "expiringSoonBadge": "Sắp hết hạn", + "freeTier": "Gói miễn phí", + "freeTierAvailable": "Có sẵn gói miễn phí", + "hasFreeTooltip": "Có sẵn gói miễn phí", + "noAuthLabel": "Không xác thực", + "noAuthProviders": "Nhà cung cấp không yêu cầu xác thực", + "upstreamProxyLabel": "Proxy ngược dòng", + "freeAggregated": "Tất cả các nhà cung cấp có gói miễn phí (cũng được hiển thị trong danh mục gốc của họ)", + "deprecated": "Không còn được hỗ trợ", + "deprecatedProvider": "Nhà cung cấp này đã không còn được hỗ trợ", "riskNotice": { - "title": "__MISSING__:Before continuing", - "tooltip": "__MISSING__:Provider with usage caveats — click for details", - "oauth": "__MISSING__:This provider uses your official product session/OAuth, which is not authorized for proxy/router use. We don't recommend intensive autonomous agent usage (OpenCloud-style, long multi-step flows, large batches) — the upstream may react by restricting or banning the account. Use at your own risk.", - "webCookie": "__MISSING__:This provider authenticates through your web session cookies. The upstream service may invalidate the session at any time, requiring you to log in again. Not recommended for long unattended operations. Use at your own risk.", - "deprecated": "__MISSING__:This provider was discontinued by its upstream and may stop working without notice. Existing connections may continue working until the upstream fully removes access. Consider alternatives.", - "dontShowAgain": "__MISSING__:Don't show this again for this provider", - "understand": "__MISSING__:I understand, continue", - "cancel": "__MISSING__:Cancel" + "title": "Trước khi tiếp tục", + "tooltip": "Nhà cung cấp có lưu ý về mức sử dụng — nhấp để xem chi tiết", + "oauth": "Nhà cung cấp này sử dụng phiên đăng nhập/OAuth chính thức của sản phẩm, vốn không được cấp phép để dùng làm proxy/bộ định tuyến. Chúng tôi không khuyến khích sử dụng tác nhân tự trị cường độ cao (kiểu OpenCloud, luồng nhiều bước kéo dài, các lô lớn) — dịch vụ ngược dòng có thể phản ứng bằng cách hạn chế hoặc cấm tài khoản. Tự chịu rủi ro khi sử dụng.", + "webCookie": "Nhà cung cấp này xác thực thông qua cookie phiên web của bạn. Dịch vụ ngược dòng có thể vô hiệu hóa phiên bất kỳ lúc nào, yêu cầu bạn phải đăng nhập lại. Không khuyến khích cho các hoạt động dài hạn không có sự giám sát. Tự chịu rủi ro khi sử dụng.", + "deprecated": "Nhà cung cấp này đã bị ngừng hoạt động bởi dịch vụ ngược dòng của nó và có thể ngừng hoạt động mà không cần báo trước. Các kết nối hiện tại có thể tiếp tục hoạt động cho đến khi dịch vụ ngược dòng loại bỏ hoàn toàn quyền truy cập. Hãy cân nhắc các giải pháp thay thế.", + "dontShowAgain": "Không hiển thị lại thông báo này cho nhà cung cấp này", + "understand": "Tôi đã hiểu, tiếp tục", + "cancel": "Hủy" }, "disabled": "Đã tắt", - "enableProvider": "Kích hoạt nhà cung cấp", - "disableProvider": "Vô hiệu hóa nhà cung cấp", + "enableProvider": "Bật nhà cung cấp", + "disableProvider": "Tắt nhà cung cấp", "testResults": "Kết quả kiểm tra", "noCompatibleYet": "Chưa có nhà cung cấp tương thích nào được thêm vào", - "compatibleHint": "Sử dụng các nút ở trên để thêm điểm cuối tương thích với OpenAI hoặc Anthropic", - "addOpenAICompatible": "Thêm tương thích OpenAI", - "addAnthropicCompatible": "Thêm tính tương thích với con người", + "compatibleHint": "Sử dụng các nút phía trên để thêm các endpoint tương thích với OpenAI hoặc Anthropic", + "addOpenAICompatible": "Thêm nhà cung cấp tương thích với OpenAI", + "addAnthropicCompatible": "Thêm nhà cung cấp tương thích với Anthropic", "addNewProvider": "Thêm nhà cung cấp mới", - "backToProviders": "Quay lại Nhà cung cấp", - "configureNewProvider": "Định cấu hình nhà cung cấp AI mới để sử dụng với các ứng dụng của bạn.", - "providerLabel": "nhà cung cấp", - "selectProvider": "Chọn nhà cung cấp", + "backToProviders": "Quay lại danh sách nhà cung cấp", + "configureNewProvider": "Cấu hình nhà cung cấp AI mới để sử dụng với các ứng dụng của bạn.", + "providerLabel": "Nhà cung cấp", + "selectProvider": "Chọn một nhà cung cấp", "selectedProvider": "Nhà cung cấp đã chọn", "authMethod": "Phương thức xác thực", "apiKeyLabel": "Khóa API", - "apiKeyRequired": "Cần có khóa API", + "apiKeyRequired": "Yêu cầu phải có khóa API", "selectProviderRequired": "Vui lòng chọn nhà cung cấp", "enterApiKey": "Nhập khóa API của bạn", "apiKeySecure": "Khóa API của bạn sẽ được mã hóa và lưu trữ an toàn.", @@ -3721,264 +4060,264 @@ "oauth2Label": "OAuth2", "oauth2Desc": "Kết nối tài khoản của bạn bằng xác thực OAuth2.", "displayName": "Tên hiển thị", - "displayNamePlaceholder": "ví dụ: API sản xuất, Môi trường phát triển", - "displayNameHint": "Tùy chọn. Một cái tên thân thiện để xác định cấu hình này.", - "active": "Đang hoạt động", - "activeDescription": "Cho phép nhà cung cấp này sử dụng trong các ứng dụng của bạn", - "cancel": "Hủy bỏ", + "displayNamePlaceholder": "Ví dụ: API sản xuất, môi trường phát triển", + "displayNameHint": "Tùy chọn. Tên dễ nhận biết để xác định cấu hình này.", + "active": "Hoạt động", + "activeDescription": "Kích hoạt nhà cung cấp này để sử dụng trong các ứng dụng của bạn", + "cancel": "Hủy", "createProvider": "Tạo nhà cung cấp", - "failedCreate": "Không tạo được nhà cung cấp", + "failedCreate": "Không thể tạo nhà cung cấp", "errorOccurred": "Đã xảy ra lỗi. Vui lòng thử lại.", - "modelStatus": "Tình trạng mẫu", - "showConfiguredOnly": "Configured only", - "allModelsOperational": "Tất cả các mô hình hoạt động", - "modelsWithIssues": "{count} mô hình có vấn đề", - "allModelsNormal": "Tất cả các model đều phản hồi bình thường.", - "cooldownCleared": "Đã xóa thời gian hồi chiêu cho {model}", - "failedClearCooldown": "Không thể xóa thời gian hồi chiêu", - "loadingAvailability": "Đang tải tính khả dụng của mô hình...", + "modelStatus": "Trạng thái mô hình", + "showConfiguredOnly": "Chỉ hiển thị các mục đã cấu hình", + "allModelsOperational": "Tất cả mô hình đang hoạt động bình thường", + "modelsWithIssues": "{count} mô hình gặp sự cố", + "allModelsNormal": "Tất cả mô hình đều đang phản hồi bình thường.", + "cooldownCleared": "Đã xóa thời gian chờ cho {model}", + "failedClearCooldown": "Không thể xóa thời gian chờ", + "loadingAvailability": "Đang tải trạng thái khả dụng của mô hình...", "clearCooldown": "Xóa", - "clearing": "Đang dọn dẹp...", - "until": "Cho đến {time}", - "providerTestFailed": "Kiểm tra nhà cung cấp không thành công", - "providerTestTimeout": "Provider test timed out — too many connections to test at once", - "modeTest": "{mode} Kiểm tra", - "passedCount": "{count} đã vượt qua", - "failedCount": "{count} không thành công", + "clearing": "Đang xóa...", + "until": "Đến {time}", + "providerTestFailed": "Kiểm tra nhà cung cấp thất bại", + "providerTestTimeout": "Kiểm tra nhà cung cấp đã quá thời gian — có quá nhiều kết nối được kiểm tra cùng lúc", + "modeTest": "Kiểm tra {mode}", + "passedCount": "{count} đạt", + "failedCount": "{count} thất bại", "testedCount": "{count} đã kiểm tra", "millisecondsAbbr": "{value}ms", - "okShort": "được rồi", + "okShort": "OK", "errorShort": "LỖI", - "noActiveConnectionsInGroup": "Không tìm thấy kết nối hoạt động nào cho nhóm này.", - "allTestsPassed": "Tất cả {total} bài kiểm tra đã vượt qua", - "testSummary": "{passed}/{total} đã đạt, {failed} không thành công", + "noActiveConnectionsInGroup": "Không tìm thấy kết nối đang hoạt động nào cho nhóm này.", + "allTestsPassed": "Tất cả {total} bài kiểm tra đã đạt", + "testSummary": "{passed}/{total} đạt, {failed} thất bại", "nameLabel": "Tên", "prefixLabel": "Tiền tố", "baseUrlLabel": "URL cơ sở", "apiTypeLabel": "Loại API", - "prefixHint": "Bắt buộc. Tiền tố duy nhất cho tên model.", - "nameHint": "Bắt buộc. Một nhãn thân thiện cho nút này.", + "prefixHint": "Bắt buộc. Tiền tố duy nhất cho tên mô hình.", + "nameHint": "Bắt buộc. Nhãn dễ nhận biết cho nút này.", "baseUrlHint": "Bắt buộc. URL cơ sở API của nhà cung cấp.", "anthropicPrefixPlaceholder": "ac-prod", "openaiPrefixPlaceholder": "oc-prod", "anthropicBaseUrlPlaceholder": "https://api.anthropic.com/v1", "openaiBaseUrlPlaceholder": "https://api.openai.com/v1", - "validateConnection": "Xác thực kết nối", - "validating": "Đang xác thực...", - "connectionValid": "Kết nối là hợp lệ!", - "connectionFailed": "Kết nối không thành công. Kiểm tra URL và khóa.", - "testKeyLabel": "Khóa API kiểm tra", - "testKeyPlaceholder": "sk-... (chỉ để xác nhận)", + "validateConnection": "Kiểm tra kết nối", + "validating": "Đang kiểm tra...", + "connectionValid": "Kết nối hợp lệ!", + "connectionFailed": "Kết nối thất bại. Vui lòng kiểm tra URL và khóa API.", + "testKeyLabel": "Khóa API để kiểm tra", + "testKeyPlaceholder": "sk-... (chỉ dùng để kiểm tra)", "providerNotFound": "Không tìm thấy nhà cung cấp", "deleteConnectionConfirm": "Xóa kết nối này?", "deleteConnectionConfirmNamed": "Bạn có chắc chắn muốn xóa {name} không? Hành động này không thể hoàn tác.", - "batchDeleteSelected": "Delete Selected ({count})", - "batchDeleteConfirm": "Delete {count} connection(s)? This action cannot be undone.", - "batchDeleteSuccess": "Deleted {count} connection(s)", - "batchActivateSelected": "__MISSING__:Activate", - "batchDeactivateSelected": "__MISSING__:Deactivate", - "batchRetestSelected": "__MISSING__:Retest", - "batchActivateSuccess": "__MISSING__:Activated {count} connection(s)", - "batchDeactivateSuccess": "__MISSING__:Deactivated {count} connection(s)", - "batchUpdatePartial": "__MISSING__:{count} updated, {skipped} skipped (no longer exist)", - "batchUpdateNone": "__MISSING__:No connections were updated (they may no longer exist)", - "batchRetestLimit": "__MISSING__:Retest up to {max} connections at a time", - "noConnectionsToTest": "__MISSING__:No matching connections to test", - "failedSetAlias": "Không đặt được bí danh", - "failedSaveConnection": "Không lưu được kết nối", - "failedSaveConnectionRetry": "Không lưu được kết nối. Vui lòng thử lại.", + "batchDeleteSelected": "Xóa mục đã chọn ({count})", + "batchDeleteConfirm": "Xóa {count} kết nối? Hành động này không thể hoàn tác.", + "batchDeleteSuccess": "Đã xóa {count} kết nối", + "batchActivateSelected": "Kích hoạt", + "batchDeactivateSelected": "Hủy kích hoạt", + "batchRetestSelected": "Kiểm tra lại", + "batchActivateSuccess": "Đã kích hoạt {count} kết nối", + "batchDeactivateSuccess": "Đã hủy kích hoạt {count} kết nối", + "batchUpdatePartial": "Đã cập nhật {count}, bỏ qua {skipped} (không còn tồn tại)", + "batchUpdateNone": "Không có kết nối nào được cập nhật (có thể chúng không còn tồn tại)", + "batchRetestLimit": "Kiểm tra lại tối đa {max} kết nối cùng lúc", + "noConnectionsToTest": "Không có kết nối phù hợp để kiểm tra", + "failedSetAlias": "Không thể đặt bí danh", + "failedSaveConnection": "Không thể lưu kết nối", + "failedSaveConnectionRetry": "Không thể lưu kết nối. Vui lòng thử lại.", "failedRetestConnection": "Không thể kiểm tra lại kết nối", - "deleteCompatibleNodeConfirm": "Xóa nút tương thích {type} này?", - "anthropicCompatibleDetails": "Chi tiết tương thích nhân loại", - "openaiCompatibleDetails": "Chi tiết tương thích OpenAI", - "messagesApi": "API tin nhắn", - "responsesApi": "API phản hồi", - "embeddings": "Embeddings", - "audioTranscriptions": "Audio Transcriptions", - "audioSpeech": "Audio Speech", - "imagesGenerations": "Images Generations", - "chatCompletions": "Hoàn thành cuộc trò chuyện", - "importingModels": "Đang nhập khẩu...", - "importFromModels": "Nhập từ /model", - "modelsImported": "{count} models imported", + "deleteCompatibleNodeConfirm": "Xóa nút tương thích với {type} này?", + "anthropicCompatibleDetails": "Chi tiết tương thích với Anthropic", + "openaiCompatibleDetails": "Chi tiết tương thích với OpenAI", + "messagesApi": "API Tin nhắn", + "responsesApi": "API Phản hồi", + "embeddings": "Mã nhúng", + "audioTranscriptions": "Chép lời âm thanh", + "audioSpeech": "Chuyển văn bản thành giọng nói", + "imagesGenerations": "Tạo ảnh", + "chatCompletions": "Hoàn tất trò chuyện", + "importingModels": "Đang nhập...", + "importFromModels": "Nhập từ /models", + "modelsImported": "Đã nhập {count} mô hình", "allModelsAlreadyImported": "Tất cả mô hình đã được nhập", - "noNewModelsToImport": "Không có mô hình mới để nhập — tất cả mô hình đã có trong danh mục hoặc danh sách mô hình tùy chỉnh", - "skippingExistingModels": "Bỏ qua {count} mô hình hiện có", + "noNewModelsToImport": "Không có mô hình mới để nhập — tất cả mô hình đã có trong sổ đăng ký hoặc danh sách mô hình tùy chỉnh", + "skippingExistingModels": "Bỏ qua {count} mô hình đã tồn tại", "autoSync": "Tự động đồng bộ hóa", - "autoSyncTooltip": "Tự động làm mới danh sách mô hình sau mỗi 24 giờ (có thể định cấu hình qua MODEL_SYNC_INTERVAL_HOURS)", - "autoSyncEnabled": "Đã bật tự động đồng bộ hóa - các mô hình sẽ làm mới định kỳ", - "autoSyncDisabled": "Tự động đồng bộ hóa đã bị tắt", - "autoSyncToggleFailed": "Không chuyển đổi được tính năng tự động đồng bộ hóa", - "clearAllModels": "Xóa tất cả các mẫu", - "clearAllModelsConfirm": "Bạn có chắc chắn muốn xóa tất cả mô hình của nhà cung cấp này không? Điều này không thể hoàn tác được.", - "clearAllModelsSuccess": "Tất cả các mô hình đã bị xóa", - "clearAllModelsFailed": "Không xóa được mô hình", - "addConnectionToImport": "Thêm kết nối để cho phép nhập.", - "noModelsConfigured": "Không có mô hình nào được định cấu hình", + "autoSyncTooltip": "Tự động làm mới danh sách mô hình sau mỗi 24 giờ (có thể cấu hình qua MODEL_SYNC_INTERVAL_HOURS)", + "autoSyncEnabled": "Đã bật tự động đồng bộ hóa — các mô hình sẽ được làm mới định kỳ", + "autoSyncDisabled": "Đã tắt tự động đồng bộ hóa", + "autoSyncToggleFailed": "Không thể chuyển đổi trạng thái tự động đồng bộ hóa", + "clearAllModels": "Xóa tất cả mô hình", + "clearAllModelsConfirm": "Bạn có chắc chắn muốn xóa tất cả mô hình của nhà cung cấp này không? Hành động này không thể hoàn tác.", + "clearAllModelsSuccess": "Đã xóa tất cả mô hình", + "clearAllModelsFailed": "Không thể xóa các mô hình", + "addConnectionToImport": "Thêm một kết nối để cho phép nhập.", + "noModelsConfigured": "Không có mô hình nào được cấu hình", "connectionCount": "{count} kết nối", - "fetchingModels": "Đang tìm nạp các mẫu có sẵn...", - "failedFetchModels": "Không tìm nạp được mô hình", + "fetchingModels": "Đang tìm nạp các mô hình khả dụng...", + "failedFetchModels": "Không thể tìm nạp các mô hình", "noModelsFound": "Không tìm thấy mô hình nào", - "importFailed": "Nhập không thành công", - "noNewModelsAdded": "Không có mô hình mới được thêm vào.", - "adding": "Đang thêm...", - "close": "Close", + "importFailed": "Nhập thất bại", + "noNewModelsAdded": "Không có mô hình mới nào được thêm vào.", + "adding": "Đang thêm…", + "close": "Đóng", "importingModelsTitle": "Nhập mô hình", "copyModel": "Sao chép mô hình", - "filterModels": "Lọc mô hình…", - "modelsActive": "đang hoạt động", + "filterModels": "Lọc mô hình...", + "modelsActive": "Đang hoạt động", "showModel": "Hiển thị mô hình", "hideModel": "Ẩn mô hình", "removeModel": "Xóa mô hình", "rateLimitProtected": "Được bảo vệ", - "rateLimitUnprotected": "không được bảo vệ", - "enableRateLimitProtection": "Nhấp để bật bảo vệ giới hạn tỷ lệ", - "disableRateLimitProtection": "Nhấp để tắt bảo vệ giới hạn tỷ lệ", - "productionKey": "Khóa sản xuất", + "rateLimitUnprotected": "Không được bảo vệ", + "enableRateLimitProtection": "Nhấp để bật bảo vệ giới hạn tần suất yêu cầu", + "disableRateLimitProtection": "Nhấp để tắt bảo vệ giới hạn tần suất yêu cầu", + "productionKey": "Khóa môi trường production", "enterNewApiKey": "Nhập khóa API mới", - "codexApplyModalTitle": "Áp dụng cho Codex địa phương", + "codexApplyModalTitle": "Áp dụng cho Local Codex", "codexApplyTargetLabel": "Đường dẫn đích", - "codexApplyBackupLabel": "Sao lưu", - "codexApplyWarning": "Điều này sẽ thay thế auth.json hiện có. Tiếp tục?", - "codexApplyConfirmCheckbox": "Tôi xác nhận rằng tôi muốn thay thế auth.json hiện có", + "codexApplyBackupLabel": "Bản sao lưu", + "codexApplyWarning": "Hành động này sẽ thay thế tệp auth.json hiện có. Tiếp tục?", + "codexApplyConfirmCheckbox": "Tôi xác nhận muốn thay thế tệp auth.json hiện có", "codexApply": "Áp dụng", - "bulkTabSingle": "Độc thân", + "bulkTabSingle": "Đơn lẻ", "bulkTabBulkAdd": "Thêm hàng loạt", - "bulkAddFormatHint": "Một phím trên mỗi dòng. Định dạng: name|apiKey hoặc chỉ apiKey (được đặt tên tự động theo chỉ mục).", + "bulkAddFormatHint": "Mỗi dòng một khóa. Định dạng: name|apiKey hoặc chỉ apiKey (sẽ tự động đặt tên theo chỉ mục).", "bulkValidateKeys": "Xác thực từng khóa trước khi lưu (chậm hơn)", - "bulkAddAllKeys": "Thêm tất cả các phím", - "bulkAddedCount": "{count, plural, one {# key added} other {# keys added}}", - "bulkFailedCount": "{count, plural, one {# failed} other {# failed}}", + "bulkAddAllKeys": "Thêm tất cả các khóa", + "bulkAddedCount": "{count, plural, one {Đã thêm # khóa} other {Đã thêm # khóa}}", + "bulkFailedCount": "{count, plural, one {# thất bại} other {# thất bại}}", "optional": "Tùy chọn", - "anthropicCompatibleName": "Tương thích với con người", + "anthropicCompatibleName": "Tương thích Anthropic", "openaiCompatibleName": "Tương thích OpenAI", - "failedImportModels": "Không thể nhập mô hình", - "noModelsReturnedFromEndpoint": "Không có mô hình nào được trả về từ điểm cuối /models.", - "importingModelsProgress": "Đang nhập {current} trong số {total} mô hình...", - "foundModelsStartingImport": "Đã tìm thấy mô hình {count}. Đang bắt đầu nhập...", + "failedImportModels": "Không thể nhập các mô hình", + "noModelsReturnedFromEndpoint": "Không có mô hình nào được trả về từ endpoint /models.", + "importingModelsProgress": "Đang nhập {current} trên {total} mô hình...", + "foundModelsStartingImport": "Tìm thấy {count} mô hình. Đang bắt đầu nhập...", "importingModelById": "Đang nhập {modelId}...", - "importSuccessCount": "Đã nhập thành công {count, plural, one {# model} other {# models}}!", - "noNewModelsAddedExisting": "Không có mẫu mới nào được thêm vào (tất cả đều đã tồn tại).", - "importDoneCount": "✓ Xong! {count, plural, one {# model imported.} other {# models imported.}}", + "importSuccessCount": "Đã nhập thành công {count, plural, one {# mô hình} other {# mô hình}}!", + "noNewModelsAddedExisting": "Không có mô hình mới nào được thêm (tất cả đã tồn tại).", + "importDoneCount": "✓ Hoàn tất! {count, plural, one {Đã nhập # mô hình.} other {Đã nhập # mô hình.}}", "unexpectedErrorOccurred": "Đã xảy ra lỗi không mong muốn", - "connectionCountLabel": "{count, plural, one {# connection} other {# connections}}", - "messagesPath": "tin nhắn", - "responsesPath": "phản hồi", - "chatCompletionsPath": "trò chuyện/hoàn thành", + "connectionCountLabel": "{count, plural, one {# kết nối} other {# kết nối}}", + "messagesPath": "messages", + "responsesPath": "responses", + "chatCompletionsPath": "chat/completions", "add": "Thêm", "edit": "Chỉnh sửa", "delete": "Xóa", - "anthropic": "nhân loại", + "anthropic": "Anthropic", "openai": "OpenAI", - "singleConnectionPerCompatible": "Chỉ có một kết nối được phép cho mỗi nút tương thích. Thêm một nút khác nếu bạn cần thêm kết nối.", + "singleConnectionPerCompatible": "Chỉ cho phép một kết nối trên mỗi nút tương thích. Thêm một nút khác nếu bạn cần nhiều kết nối hơn.", "connections": "Kết nối", "providerProxyTitleConfigured": "Proxy của nhà cung cấp: {host}", - "configured": "được cấu hình", - "providerProxyConfigureHint": "Định cấu hình proxy cho tất cả các kết nối của nhà cung cấp này", - "providerProxy": "Ủy quyền của nhà cung cấp", - "repairEnv": "Repair env", - "repairEnvWorking": "Repairing...", - "repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.", - "repairEnvSuccess": "OAuth defaults restored", - "repairEnvFailed": "Failed to repair .env", + "configured": "đã cấu hình", + "providerProxyConfigureHint": "Cấu hình proxy cho tất cả kết nối của nhà cung cấp này", + "providerProxy": "Proxy của nhà cung cấp", + "repairEnv": "Sửa .env", + "repairEnvWorking": "Đang sửa...", + "repairEnvHint": "Khôi phục các giá trị OAuth mặc định bị thiếu vào .env mà không ghi đè lên các giá trị hiện có.", + "repairEnvSuccess": "Đã khôi phục các giá trị OAuth mặc định", + "repairEnvFailed": "Không thể sửa .env", "noConnectionsYet": "Chưa có kết nối nào", "addFirstConnectionHint": "Thêm kết nối đầu tiên của bạn để bắt đầu", "addConnection": "Thêm kết nối", - "availableModels": "Các mẫu có sẵn", - "builtInModels": "Built-in models", - "builtInModelsHint": "Registry models for this provider. Use the pencil to set compatibility options.", + "availableModels": "Mô hình có sẵn", + "builtInModels": "Mô hình tích hợp", + "builtInModelsHint": "Các mô hình trong danh mục của nhà cung cấp này. Sử dụng biểu tượng bút chì để thiết lập các tùy chọn tương thích.", "pageAutoRefresh": "Trang sẽ tự động làm mới...", - "statusDisabled": "bị vô hiệu hóa", + "statusDisabled": "đã vô hiệu hóa", "statusConnected": "đã kết nối", - "statusRuntimeIssue": "vấn đề thời gian chạy", + "statusRuntimeIssue": "sự cố môi trường chạy", "statusAuthFailed": "xác thực thất bại", - "statusRateLimited": "tỷ lệ giới hạn", + "statusRateLimited": "bị giới hạn lượt yêu cầu", "statusNetworkIssue": "sự cố mạng", "statusTestUnsupported": "kiểm tra không được hỗ trợ", - "statusUnavailable": "không có sẵn", + "statusUnavailable": "không khả dụng", "statusFailed": "thất bại", "statusError": "lỗi", "oauthAccount": "Tài khoản OAuth", - "errorTypeRuntime": "Thời gian chạy cục bộ", - "errorTypeUpstreamAuth": "Xác thực ngược dòng", + "errorTypeRuntime": "Môi trường chạy cục bộ", + "errorTypeUpstreamAuth": "Xác thực máy chủ phía trên", "errorTypeMissingCredential": "Thiếu thông tin xác thực", - "errorTypeRefreshFailed": "Làm mới không thành công", - "errorTypeTokenExpired": "Mã thông báo đã hết hạn", - "errorTypeRateLimited": "Tỷ lệ giới hạn", - "errorTypeUpstreamUnavailable": "Thượng nguồn không có sẵn", + "errorTypeRefreshFailed": "Làm mới thất bại", + "errorTypeTokenExpired": "Token đã hết hạn", + "errorTypeRateLimited": "Bị giới hạn tần suất", + "errorTypeUpstreamUnavailable": "Máy chủ phía trên không khả dụng", "errorTypeNetworkError": "Lỗi mạng", - "errorTypeTestUnsupported": "Kiểm tra không được hỗ trợ", - "errorTypeUpstreamError": "Lỗi ngược dòng", + "errorTypeTestUnsupported": "Không hỗ trợ kiểm tra", + "errorTypeUpstreamError": "Lỗi từ máy chủ phía trên", "proxySourceGlobal": "Toàn cầu", - "proxySourceProvider": "nhà cung cấp", - "proxySourceKey": "Chìa khóa", - "proxyConfiguredBySource": "Ủy quyền ({source}): {host}", + "proxySourceProvider": "Nhà cung cấp", + "proxySourceKey": "Khóa", + "proxyConfiguredBySource": "Proxy ({source}): {host}", "autoPriority": "Tự động: {priority}", - "proxy": "ủy nhiệm", + "proxy": "Proxy", "retestAuthentication": "Kiểm tra lại xác thực", "retest": "Kiểm tra lại", - "disableConnection": "Tắt kết nối", + "disableConnection": "Vô hiệu hóa kết nối", "enableConnection": "Kích hoạt kết nối", "reauthenticateConnection": "Xác thực lại kết nối này", "proxyConfig": "Cấu hình proxy", "aliasExistsAlert": "Bí danh \"{alias}\" đã tồn tại. Vui lòng sử dụng một mô hình khác hoặc chỉnh sửa bí danh hiện có.", - "aliasInputPlaceholder": "alias name", - "clickToSetAlias": "Click to set alias", - "clickToEditAlias": "Alias: {alias} (click to edit)", + "aliasInputPlaceholder": "tên bí danh", + "clickToSetAlias": "Nhấp để đặt bí danh", + "clickToEditAlias": "Bí danh: {alias} (nhấp để chỉnh sửa)", "openRouterAnyModelHint": "OpenRouter hỗ trợ mọi mô hình. Thêm mô hình và tạo bí danh để truy cập nhanh.", - "modelIdFromOpenRouter": "ID mẫu (từ OpenRouter)", - "openRouterModelPlaceholder": "nhân chủng/claude-3-opus", + "modelIdFromOpenRouter": "ID mô hình (từ OpenRouter)", + "openRouterModelPlaceholder": "anthropic/claude-3-opus", "customModels": "Mô hình tùy chỉnh", - "customModelsHint": "Thêm ID mẫu không có trong danh sách mặc định. Chúng sẽ có sẵn để định tuyến.", - "normalizeToolCallIdLabel": "Normalize tool call IDs to 9 characters (e.g. Mistral)", - "preserveDeveloperRoleLabel": "Keep OpenAI Responses developer role (do not map to system)", - "compatAdjustmentsTitle": "Compatibility", - "compatButtonLabel": "Compatibility", - "compatToolIdShort": "Tool ID 9", - "compatDeveloperShort": "Developer role", - "compatDoNotPreserveDeveloper": "Do not preserve developer role", - "compatBadgeNoPreserve": "No preserve", - "compatProtocolLabel": "Client request protocol", - "compatProtocolHint": "These options apply when OmniRoute detects this request shape (OpenAI Chat, Responses API, or Anthropic Messages).", + "customModelsHint": "Thêm các ID mô hình không có trong danh sách mặc định. Chúng sẽ sẵn sàng để định tuyến.", + "normalizeToolCallIdLabel": "Chuẩn hóa ID lệnh gọi công cụ thành 9 ký tự (ví dụ: Mistral)", + "preserveDeveloperRoleLabel": "Giữ vai trò nhà phát triển trong OpenAI Responses (không ánh xạ sang hệ thống)", + "compatAdjustmentsTitle": "Tính tương thích", + "compatButtonLabel": "Tính tương thích", + "compatToolIdShort": "ID công cụ 9", + "compatDeveloperShort": "Vai trò nhà phát triển", + "compatDoNotPreserveDeveloper": "Không giữ vai trò nhà phát triển", + "compatBadgeNoPreserve": "Không giữ lại", + "compatProtocolLabel": "Giao thức yêu cầu của ứng dụng khách", + "compatProtocolHint": "Các tùy chọn này áp dụng khi OmniRoute phát hiện dạng yêu cầu này (OpenAI Chat, Responses API hoặc Anthropic Messages).", "compatProtocolOpenAI": "OpenAI Chat Completions", "compatProtocolOpenAIResponses": "OpenAI Responses API", "compatProtocolClaude": "Anthropic Messages", - "compatUpstreamHeadersLabel": "Extra upstream headers", - "compatUpstreamHeadersHint": "High-privilege setting — same trust level as editing provider API credentials; only trusted admins should use it. Merged after OmniRoute adds auth from the provider API key. If a custom header uses the same name as an existing one (e.g. Authorization), your value fully replaces the auto-generated header (including the Bearer token) — the upstream only sees what you typed, not the key from settings. Misconfiguration can cause 401 or broken upstream auth. One row per header (e.g. extra Authentication for some gateways). Hover or focus the value to preview. Saves on blur, outside click, or closing this panel.", - "compatUpstreamHeaderName": "Header name", - "compatUpstreamHeaderValue": "Value", - "compatUpstreamAddRow": "Add header", - "compatUpstreamRemoveRow": "Remove row", - "compatBadgeUpstreamHeaders": "Headers", - "perModelQuotaLabel": "Per Model Quota Label", - "perModelQuotaDescription": "Per Model Quota Description", - "perModelQuotaToggle": "Chuyển đổi hạn ngạch cho mỗi mô hình", - "modelId": "Mã mẫu", + "compatUpstreamHeadersLabel": "Các header upstream bổ sung", + "compatUpstreamHeadersHint": "Cài đặt có đặc quyền cao — có cùng mức độ tin cậy như khi chỉnh sửa thông tin xác thực API của nhà cung cấp; chỉ quản trị viên đáng tin cậy mới nên sử dụng. Các header này được hợp nhất sau khi OmniRoute thêm thông tin xác thực từ khóa API của nhà cung cấp. Nếu một header tùy chỉnh có cùng tên với header hiện có (ví dụ: Authorization), giá trị của bạn sẽ thay thế hoàn toàn header được tạo tự động (bao gồm cả token Bearer) — máy chủ thượng nguồn chỉ nhận được nội dung bạn đã nhập, không phải khóa trong phần cài đặt. Cấu hình sai có thể gây ra lỗi 401 hoặc làm hỏng quá trình xác thực với máy chủ thượng nguồn. Mỗi hàng tương ứng với một header (ví dụ: header Authentication bổ sung cho một số cổng). Di chuột hoặc đặt tiêu điểm vào giá trị để xem trước. Tự động lưu khi mất tiêu điểm, nhấp ra ngoài hoặc đóng bảng điều khiển này.", + "compatUpstreamHeaderName": "Tên header", + "compatUpstreamHeaderValue": "Giá trị", + "compatUpstreamAddRow": "Thêm header", + "compatUpstreamRemoveRow": "Xóa hàng", + "compatBadgeUpstreamHeaders": "Header", + "perModelQuotaLabel": "Hạn ngạch cho mỗi mô hình", + "perModelQuotaDescription": "Khi được bật, lỗi 429/404 chỉ khóa mô hình cụ thể đó chứ không khóa toàn bộ kết nối. Sử dụng cho các nhà cung cấp có giới hạn tốc độ cho từng mô hình (ví dụ: ModelScope).", + "perModelQuotaToggle": "Bật/tắt hạn ngạch cho mỗi mô hình", + "modelId": "ID mô hình", "customModelPlaceholder": "ví dụ: gpt-4.5-turbo", "loading": "Đang tải...", "removeCustomModel": "Xóa mô hình tùy chỉnh", "noCustomModels": "Chưa có mô hình tùy chỉnh nào được thêm vào.", - "allSuggestedAliasesExist": "Tất cả các bí danh được đề xuất đã tồn tại. Vui lòng chọn một mẫu khác hoặc xóa các bí danh xung đột.", + "allSuggestedAliasesExist": "Tất cả các bí danh được đề xuất đã tồn tại. Vui lòng chọn một mô hình khác hoặc xóa các bí danh xung đột.", "failedSaveCustomModel": "Không lưu được mô hình tùy chỉnh", "modelAddedSuccess": "Đã thêm mô hình {modelId} thành công", "failedAddModelTryAgain": "Không thể thêm mô hình. Vui lòng thử lại.", "failedSaveImportedModel": "Không lưu được mô hình đã nhập vào cơ sở dữ liệu tùy chỉnh", - "failedImportModelsTryAgain": "Không thể nhập mô hình. Vui lòng thử lại.", + "failedImportModelsTryAgain": "Không thể nhập các mô hình. Vui lòng thử lại.", "failedRemoveModelFromDatabase": "Không thể xóa mô hình khỏi cơ sở dữ liệu", "modelRemovedSuccess": "Đã xóa mô hình thành công", "failedDeleteModelTryAgain": "Không xóa được mô hình. Vui lòng thử lại.", - "compatibleModelsDescription": "Thêm các mô hình tương thích {type} theo cách thủ công hoặc nhập chúng từ điểm cuối /models.", - "anthropicCompatibleModelPlaceholder": "Claude-3-opus-20240229", + "compatibleModelsDescription": "Thêm thủ công các mô hình tương thích với {type} hoặc nhập chúng từ endpoint /models.", + "anthropicCompatibleModelPlaceholder": "claude-3-opus-20240229", "openaiCompatibleModelPlaceholder": "gpt-4o", - "apiKeyValidationFailed": "Xác thực khóa API không thành công. Vui lòng kiểm tra chìa khóa của bạn và thử lại.", + "apiKeyValidationFailed": "Xác thực khóa API thất bại. Vui lòng kiểm tra khóa của bạn và thử lại.", "addProviderApiKeyTitle": "Thêm khóa API {provider}", "checking": "Đang kiểm tra...", "check": "Kiểm tra", - "valid": "hợp lệ", - "invalid": "không hợp lệ", + "valid": "Hợp lệ", + "invalid": "Không hợp lệ", "creating": "Đang tạo...", - "validationChecksAnthropicCompatible": "Kiểm tra xác thực {provider} bằng cách xác minh khóa API.", - "validationChecksOpenAiCompatible": "Kiểm tra xác thực {provider} thông qua /models trên URL cơ sở của bạn.", + "validationChecksAnthropicCompatible": "Xác thực {provider} bằng cách kiểm tra khóa API.", + "validationChecksOpenAiCompatible": "Xác thực {provider} qua /models trên URL cơ sở của bạn.", "priorityLabel": "Ưu tiên", "saving": "Đang lưu...", "save": "Lưu", @@ -3986,426 +4325,426 @@ "accountName": "Tên tài khoản", "email": "Email", "healthCheckMinutes": "Kiểm tra sức khỏe (phút)", - "healthCheckHint": "Khoảng thời gian làm mới mã thông báo chủ động. 0 = bị vô hiệu hóa.", - "selectAllModels": "Select all", - "deselectAllModels": "Deselect all", - "modelsActiveCount": "{active}/{total} active", - "noModelsMatch": "No models match \"{filter}\"", - "groupLabel": "Environment", - "groupPlaceholder": "e.g. eKaizen, Personal", + "healthCheckHint": "Khoảng thời gian chủ động làm mới token. 0 = vô hiệu hóa.", + "selectAllModels": "Chọn tất cả", + "deselectAllModels": "Bỏ chọn tất cả", + "modelsActiveCount": "{active}/{total} đang hoạt động", + "noModelsMatch": "Không có mô hình nào khớp với \"{filter}\"", + "groupLabel": "Môi trường", + "groupPlaceholder": "Ví dụ: eKaizen, Cá nhân", "failedTestConnection": "Không thể kiểm tra kết nối", - "failed": "thất bại", - "leaveBlankKeepCurrentApiKey": "Để trống để giữ khóa API hiện tại.", - "editCompatibleTitle": "Chỉnh sửa {type} Tương thích", - "compatibleBaseUrlHint": "Root URL of your {type}-compatible API. Use Advanced Settings for custom endpoint paths.", - "apiKeyForCheck": "Khóa API (để kiểm tra)", - "compatibleProdPlaceholder": "{type} Tương thích (Sản phẩm)", - "tokenRefreshed": "Token refreshed successfully", - "tokenRefreshFailed": "Token refresh failed", - "applyCodexAuthLocal": "Apply auth", - "exportCodexAuthFile": "Export auth", - "applyClaudeAuthLocal": "Áp dụng xác thực", - "exportClaudeAuthFile": "Xuất xác thực", - "importClaudeAuth": "Nhập xác thực", - "claudeApplyModalTitle": "Áp dụng cho Mã Claude địa phương", + "failed": "Thất bại", + "leaveBlankKeepCurrentApiKey": "Để trống để giữ API key hiện tại.", + "editCompatibleTitle": "Chỉnh sửa cấu hình tương thích với {type}", + "compatibleBaseUrlHint": "URL gốc của API tương thích với {type} của bạn. Sử dụng Cài đặt nâng cao cho các đường dẫn endpoint tùy chỉnh.", + "apiKeyForCheck": "API key (để kiểm tra)", + "compatibleProdPlaceholder": "Cấu hình tương thích với {type} (môi trường sản xuất)", + "tokenRefreshed": "Đã làm mới token thành công", + "tokenRefreshFailed": "Làm mới token thất bại", + "applyCodexAuthLocal": "Áp dụng thông tin xác thực", + "exportCodexAuthFile": "Xuất thông tin xác thực", + "applyClaudeAuthLocal": "Áp dụng thông tin xác thực", + "exportClaudeAuthFile": "Xuất thông tin xác thực", + "importClaudeAuth": "Nhập thông tin xác thực", + "claudeApplyModalTitle": "Áp dụng cho Claude Code cục bộ", "claudeApplyTargetLabel": "Đường dẫn đích", - "claudeApplyBackupLabel": "Sao lưu", + "claudeApplyBackupLabel": "Bản sao lưu", "claudeApplyMcpHint": "Trạng thái MCP OAuth hiện tại sẽ được giữ nguyên.", - "claudeApplyWarning": "Phần này sẽ thay thế phần claudeAiOauth hiện có. Tiếp tục?", - "claudeApplyConfirmCheckbox": "Tôi xác nhận rằng tôi muốn thay thế phần claudeAiOauth hiện có", + "claudeApplyWarning": "Thao tác này sẽ thay thế phần claudeAiOauth hiện có. Tiếp tục?", + "claudeApplyConfirmCheckbox": "Tôi xác nhận muốn thay thế phần claudeAiOauth hiện có", "claudeApply": "Áp dụng", - "claudeAuthAppliedLocal": "Claude auth áp dụng tại địa phương", - "claudeAuthApplyFailed": "Không thể áp dụng Claude auth cục bộ", - "claudeAuthExported": "Đã xuất tệp xác thực Claude", - "claudeAuthExportFailed": "Không thể xuất tệp xác thực Claude", - "claudeImportModalTitle": "Nhập khẩu Claude Auth", - "claudeImportTabSingle": "Độc thân", - "claudeImportTabBulk": "số lượng lớn", - "claudeImportTabUpload": "Tải tập tin lên", + "claudeAuthAppliedLocal": "Đã áp dụng thông tin xác thực Claude cục bộ", + "claudeAuthApplyFailed": "Không thể áp dụng thông tin xác thực Claude cục bộ", + "claudeAuthExported": "Đã xuất tệp thông tin xác thực Claude", + "claudeAuthExportFailed": "Không thể xuất tệp thông tin xác thực Claude", + "claudeImportModalTitle": "Nhập thông tin xác thực Claude", + "claudeImportTabSingle": "Đơn lẻ", + "claudeImportTabBulk": "Hàng loạt", + "claudeImportTabUpload": "Tải tệp lên", "claudeImportTabPaste": "Dán JSON", "claudeImportFileLabel": "Chọn .credentials.json", "claudeImportPasteLabel": "Dán nội dung JSON", "claudeImportEmailLabel": "Email tài khoản", "claudeImportNameLabel": "Tên kết nối (tùy chọn)", "claudeImportOverwriteLabel": "Thay thế kết nối hiện tại nếu tài khoản đã tồn tại", - "claudeImportSubmit": "Nhập khẩu", - "claudeImportSuccess": "Kết nối Claude được nhập thành công", + "claudeImportSubmit": "Nhập", + "claudeImportSuccess": "Nhập kết nối Claude thành công", "claudeImportInvalidJson": "Không thể phân tích cú pháp tệp dưới dạng JSON", - "claudeImportInvalidShape": "Tệp này không phải là .credentials.json hợp lệ", - "claudeImportDuplicate": "Tài khoản đã tồn tại — bật \"Thay thế hiện tại\" để ghi đè", - "claudeImportIdentityUnverified": "Bootstrap không thể xác minh tài khoản. Bật \"Thay thế hiện tại\" hoặc cung cấp email.", - "claudeImportFailed": "Không thể nhập Claude auth", - "claudeImportBulkModeUpload": "Tải tập tin lên", + "claudeImportInvalidShape": "Tệp không phải là .credentials.json hợp lệ", + "claudeImportDuplicate": "Tài khoản đã tồn tại — bật \"Thay thế kết nối hiện tại\" để ghi đè", + "claudeImportIdentityUnverified": "Bootstrap không thể xác minh tài khoản. Hãy bật \"Thay thế kết nối hiện tại\" hoặc cung cấp email.", + "claudeImportFailed": "Không thể nhập thông tin xác thực Claude", + "claudeImportBulkModeUpload": "Tải tệp lên", "claudeImportBulkModePaste": "Dán mảng JSON", - "claudeImportBulkModeZip": "Tải lên ZIP", - "claudeImportBulkUploadHint": "Thả hoặc chọn tối đa 50 tệp .credentials.json (mỗi tệp 256KB, tổng cộng 10 MB).", + "claudeImportBulkModeZip": "Tải lên tệp ZIP", + "claudeImportBulkUploadHint": "Kéo thả hoặc chọn tối đa 50 tệp .credentials.json (tối đa 256KB mỗi tệp, tổng cộng 10MB).", "claudeImportBulkPasteHint": "Dán một mảng đối tượng: [{ json, name?, email? }...]", - "claudeImportBulkZipHint": "ZIP chứa các mục .json. Tối đa 50 mục, giải nén 10 MB.", + "claudeImportBulkZipHint": "Tệp ZIP chứa các mục .json. Tối đa 50 mục, giải nén tối đa 10MB.", "claudeImportBulkSubmit": "Nhập tất cả", "claudeImportBulkSuccess": "Đã nhập {count} kết nối Claude", - "claudeImportBulkFailed": "Một số mục không thể nhập được", - "claudeImportBulkZipExtracting": "Đang giải nén ZIP…", - "claudeImportBulkZipError": "Không thể giải nén ZIP", - "geminiAuthAppliedLocal": "Xác thực Gemini được áp dụng cục bộ", - "geminiAuthApplyFailed": "Không thể áp dụng xác thực Gemini cục bộ", - "geminiAuthExported": "Đã xuất tệp xác thực Gemini", - "geminiAuthExportFailed": "Không xuất được tệp xác thực Gemini", - "geminiImportModalTitle": "Nhập khẩu Gemini Auth", - "geminiImportTabSingle": "Độc thân", - "geminiImportTabBulk": "số lượng lớn", - "geminiImportTabUpload": "Tải tập tin lên", + "claudeImportBulkFailed": "Không thể nhập một số mục", + "claudeImportBulkZipExtracting": "Đang giải nén tệp ZIP…", + "claudeImportBulkZipError": "Không thể giải nén tệp ZIP", + "geminiAuthAppliedLocal": "Đã áp dụng thông tin xác thực Gemini trên máy cục bộ", + "geminiAuthApplyFailed": "Không thể áp dụng thông tin xác thực Gemini trên máy cục bộ", + "geminiAuthExported": "Đã xuất tệp thông tin xác thực Gemini", + "geminiAuthExportFailed": "Không thể xuất tệp thông tin xác thực Gemini", + "geminiImportModalTitle": "Nhập thông tin xác thực Gemini", + "geminiImportTabSingle": "Đơn lẻ", + "geminiImportTabBulk": "Hàng loạt", + "geminiImportTabUpload": "Tải tệp lên", "geminiImportTabPaste": "Dán JSON", "geminiImportFileLabel": "Chọn oauth_creds.json", "geminiImportPasteLabel": "Dán nội dung JSON", "geminiImportEmailLabel": "Email tài khoản", "geminiImportNameLabel": "Tên kết nối (tùy chọn)", "geminiImportOverwriteLabel": "Thay thế kết nối hiện tại nếu tài khoản đã tồn tại", - "geminiImportSubmit": "Nhập khẩu", - "geminiImportSuccess": "Kết nối Gemini được nhập thành công", + "geminiImportSubmit": "Nhập", + "geminiImportSuccess": "Đã nhập kết nối Gemini thành công", "geminiImportInvalidJson": "Không thể phân tích cú pháp tệp dưới dạng JSON", - "geminiImportInvalidShape": "Tệp này không phải là oauth_creds.json hợp lệ", - "geminiImportDuplicate": "Tài khoản đã tồn tại — bật \"Thay thế hiện tại\" để ghi đè", - "geminiImportIdentityUnverified": "Không thể xác minh danh tính từ id_token. Bật \"Thay thế hiện tại\" hoặc cung cấp email.", - "geminiImportFailed": "Không thể nhập xác thực Gemini", - "geminiImportBulkModeUpload": "Tải tập tin lên", + "geminiImportInvalidShape": "Tệp không phải là oauth_creds.json hợp lệ", + "geminiImportDuplicate": "Tài khoản đã tồn tại — hãy bật \"Thay thế hiện tại\" để ghi đè", + "geminiImportIdentityUnverified": "Không thể xác minh danh tính từ id_token. Hãy bật \"Thay thế hiện tại\" hoặc cung cấp email.", + "geminiImportFailed": "Không thể nhập thông tin xác thực Gemini", + "geminiImportBulkModeUpload": "Tải các tệp lên", "geminiImportBulkModePaste": "Dán mảng JSON", - "geminiImportBulkModeZip": "Tải lên ZIP", - "geminiImportBulkUploadHint": "Thả hoặc chọn tối đa 50 tệp oauth_creds.json (mỗi tệp 256KB, tổng cộng 10 MB).", - "geminiImportBulkPasteHint": "Dán một mảng đối tượng: [{ json, name?, email? }...]", - "geminiImportBulkZipHint": "ZIP chứa các mục oauth_creds.json. Tối đa 50 mục, giải nén 10 MB.", + "geminiImportBulkModeZip": "Tải tệp ZIP lên", + "geminiImportBulkUploadHint": "Thả hoặc chọn tối đa 50 tệp oauth_creds.json (tối đa 256KB mỗi tệp, tổng cộng 10MB).", + "geminiImportBulkPasteHint": "Dán một mảng các đối tượng: [{ json, name?, email? }...]", + "geminiImportBulkZipHint": "Tệp ZIP chứa các mục oauth_creds.json. Tối đa 50 mục, tối đa 10MB sau khi giải nén.", "geminiImportBulkSubmit": "Nhập tất cả", "geminiImportBulkSuccess": "Đã nhập {count} kết nối Gemini", - "geminiImportBulkFailed": "Một số mục không thể nhập được", - "geminiImportBulkZipExtracting": "Đang giải nén ZIP…", - "geminiImportBulkZipError": "Không thể giải nén ZIP", - "codexAuthAppliedLocal": "Codex auth.json applied locally", - "codexAuthApplyFailed": "Failed to apply Codex auth.json locally", - "codexAuthExported": "Codex auth.json exported", - "codexAuthExportFailed": "Failed to export Codex auth.json", - "importCodexAuth": "Nhập xác thực", - "codexImportModalTitle": "Nhập Codex Auth", - "codexImportTabSingle": "Độc thân", - "codexImportTabBulk": "số lượng lớn", - "codexImportTabUpload": "Tải tập tin lên", + "geminiImportBulkFailed": "Không thể nhập một số mục", + "geminiImportBulkZipExtracting": "Đang giải nén tệp ZIP…", + "geminiImportBulkZipError": "Không thể giải nén tệp ZIP", + "codexAuthAppliedLocal": "Đã áp dụng Codex auth.json cục bộ", + "codexAuthApplyFailed": "Không thể áp dụng Codex auth.json cục bộ", + "codexAuthExported": "Đã xuất Codex auth.json", + "codexAuthExportFailed": "Không thể xuất Codex auth.json", + "importCodexAuth": "Nhập thông tin xác thực", + "codexImportModalTitle": "Nhập thông tin xác thực Codex", + "codexImportTabSingle": "Đơn lẻ", + "codexImportTabBulk": "Hàng loạt", + "codexImportTabUpload": "Tải tệp lên", "codexImportTabPaste": "Dán JSON", - "codexImportFileLabel": "Chọn auth.json", + "codexImportFileLabel": "Chọn tệp auth.json", "codexImportFileHint": "Chọn tệp auth.json được xuất từ Codex hoặc từ OmniRoute.", "codexImportPasteLabel": "Dán nội dung JSON", "codexImportEmailLabel": "Email tài khoản", - "codexImportEmailHint": "Tự động phát hiện từ tập tin; chỉnh sửa nếu cần thiết.", + "codexImportEmailHint": "Tự động phát hiện từ tệp; chỉnh sửa nếu cần.", "codexImportNameLabel": "Tên kết nối (tùy chọn)", "codexImportOverwriteLabel": "Thay thế kết nối hiện tại nếu tài khoản đã tồn tại", - "codexImportSubmit": "Nhập khẩu", - "codexImportSuccess": "Kết nối Codex được nhập thành công", + "codexImportSubmit": "Nhập", + "codexImportSuccess": "Đã nhập kết nối Codex thành công", "codexImportInvalidJson": "Không thể phân tích cú pháp tệp dưới dạng JSON", - "codexImportInvalidShape": "Tệp này không phải là Codex auth.json hợp lệ", - "codexImportDuplicate": "Tài khoản đã tồn tại — bật \"Thay thế hiện tại\" để ghi đè", - "codexImportFailed": "Không thể nhập xác thực Codex", - "codexImportDetectedEmail": "Đã phát hiện: {email}", - "codexImportNoEmailDetected": "Không phát hiện thấy email trong tập tin", - "codexImportBulkModeUpload": "Tải tập tin lên", + "codexImportInvalidShape": "Tệp không phải là auth.json của Codex hợp lệ", + "codexImportDuplicate": "Tài khoản đã tồn tại — hãy bật \"Thay thế kết nối hiện tại\" để ghi đè", + "codexImportFailed": "Không thể nhập thông tin xác thực Codex", + "codexImportDetectedEmail": "Phát hiện: {email}", + "codexImportNoEmailDetected": "Không phát hiện thấy email trong tệp", + "codexImportBulkModeUpload": "Tải các tệp lên", "codexImportBulkModePaste": "Dán danh sách", - "codexImportBulkModeZip": "kho lưu trữ ZIP", + "codexImportBulkModeZip": "Tệp nén ZIP", "codexImportBulkUploadHint": "Chọn nhiều tệp .json hoặc kéo và thả", - "codexImportBulkPasteHint": "Mảng JSON [ {...}, {...} ] hoặc nhiều JSON được phân tách bằng --- trên dòng riêng", - "codexImportBulkZipHint": "Tải lên tệp .zip chứa tệp auth.json (tối đa 50 tệp, 10 MB)", + "codexImportBulkPasteHint": "Mảng JSON [ {...}, {...} ] hoặc nhiều JSON được phân tách bằng dấu --- trên một dòng riêng biệt", + "codexImportBulkZipHint": "Tải lên tệp .zip chứa các tệp auth.json (tối đa 50 tệp, 10 MB)", "codexImportBulkSubmit": "Nhập {count} tài khoản", "codexImportBulkLimit": "Tối đa 50 tệp cho mỗi lần nhập", - "codexImportBulkSuccess": "{count} đã được nhập", - "codexImportBulkFailed": "{count} không thành công", + "codexImportBulkSuccess": "Đã nhập {count}", + "codexImportBulkFailed": "{count} thất bại", "codexImportBulkZipExtracting": "Đang giải nén ZIP…", "codexImportBulkZipError": "Không thể giải nén ZIP", - "advancedSettings": "Advanced Settings", - "chatPathLabel": "Chat Endpoint Path", + "advancedSettings": "Cài đặt nâng cao", + "chatPathLabel": "Đường dẫn endpoint trò chuyện", "chatPathPlaceholder": "/chat/completions", - "chatPathHint": "Custom chat path for providers with non-standard APIs (e.g. /v4/chat/completions)", - "modelsPathLabel": "Models Endpoint Path", + "chatPathHint": "Đường dẫn chat tùy chỉnh cho các nhà cung cấp có API không chuẩn (ví dụ: /v4/chat/completions)", + "modelsPathLabel": "Đường dẫn endpoint mô hình", "modelsPathPlaceholder": "/models", - "modelsPathHint": "Custom models path for validation (e.g. /v4/models)", - "statusDeactivated": "Deactivated (Manual)", - "statusBanned": "Banned / Sandbox Violation", - "statusCreditsExhausted": "Insufficient Balance / Quota Exhausted", - "showEmails": "Show all emails", - "hideEmails": "Hide all emails", + "modelsPathHint": "Đường dẫn mô hình tùy chỉnh để xác thực (ví dụ: /v4/models)", + "statusDeactivated": "Đã hủy kích hoạt (Thủ công)", + "statusBanned": "Bị cấm / Vi phạm môi trường hộp cát", + "statusCreditsExhausted": "Không đủ số dư / Hết hạn ngạch", + "showEmails": "Hiển thị tất cả email", + "hideEmails": "Ẩn tất cả email", "a": "A", - "accountConcurrencyCapHint": "Account Concurrency Cap Hint", - "accountConcurrencyCapLabel": "Account Concurrency Cap Label", - "accountIdHint": "Account Id Hint", - "accountIdLabel": "Account Id Label", - "accountIdPlaceholder": "Account Id Placeholder", - "addAnotherApiKey": "Add another API key or paste multiple keys", - "addCcCompatible": "Add Cc Compatible", - "aggregatorsGateways": "Aggregators Gateways", + "accountConcurrencyCapHint": "Số lượng yêu cầu đồng thời tối đa mà kết nối/tài khoản này có thể xử lý. Các tài khoản đăng ký trả phí thường chỉ cho phép một vài yêu cầu (1–3) — vượt quá sẽ kích hoạt lỗi 429 và thời gian chờ hồi. Để trống để dùng giá trị mặc định.", + "accountConcurrencyCapLabel": "Giới hạn số lượng yêu cầu đồng thời của tài khoản", + "accountIdHint": "Được yêu cầu bởi một số nhà cung cấp (ví dụ: Cloudflare Workers AI) cùng với API token.", + "accountIdLabel": "ID tài khoản", + "accountIdPlaceholder": "ID tài khoản nhà cung cấp của bạn", + "addAnotherApiKey": "Thêm khóa API khác hoặc dán nhiều khóa", + "addCcCompatible": "Thêm nhà cung cấp tương thích CC", + "aggregatorsGateways": "Trình tổng hợp và cổng kết nối", "enterpriseCloud": "Doanh nghiệp & Đám mây", - "apiFormatLabel": "Api Format Label", - "apiKeyOptionalHint": "Api Key Optional Hint", - "apiKeyOptionalLabel": "Api Key Optional Label", - "apiRegionChina": "Api Region China", - "apiRegionHint": "Api Region Hint", - "apiRegionInternational": "Api Region International", - "apiRegionLabel": "Api Region Label", - "apikey": "Apikey", - "audio": "Audio", - "audioProvidersHeading": "Audio Providers Heading", - "cloudAgentProviders": "Nhà cung cấp đại lý đám mây", - "audioShortLabel": "Audio Short Label", - "azureOpenAiBaseUrlHint": "Azure Open Ai Base Url Hint", - "bailianBaseUrlHint": "Bailian Base Url Hint", - "claudeWebCookieHint": "Open claude.ai → DevTools → Application → Cookies → claude.ai, copy the 'sessionKey' value. Also need cf_clearance, __cf_bm, _cfuvid for Cloudflare.", + "apiFormatLabel": "Nhãn định dạng API", + "apiKeyOptionalHint": "Gợi ý khóa API tùy chọn", + "apiKeyOptionalLabel": "Nhãn khóa API tùy chọn", + "apiRegionChina": "Khu vực API: Trung Quốc", + "apiRegionHint": "Gợi ý khu vực API", + "apiRegionInternational": "Khu vực API: Quốc tế", + "apiRegionLabel": "Khu vực API", + "apikey": "Khóa API", + "audio": "Âm thanh", + "audioProvidersHeading": "Nhà cung cấp âm thanh", + "cloudAgentProviders": "Nhà cung cấp tác nhân đám mây", + "audioShortLabel": "Âm thanh", + "azureOpenAiBaseUrlHint": "Gợi ý URL cơ sở của Azure OpenAI", + "bailianBaseUrlHint": "Gợi ý URL cơ sở của Bailian", + "claudeWebCookieHint": "Mở claude.ai → DevTools → Application → Cookies → claude.ai, sao chép giá trị 'sessionKey'. Đồng thời cũng cần các giá trị cf_clearance, __cf_bm, _cfuvid cho Cloudflare.", "claudeWebCookiePlaceholder": "sessionKey=sk-ant-...", - "blackboxWebCookieHint": "Blackbox Web Cookie Hint", - "blackboxWebCookiePlaceholder": "Blackbox Web Cookie Placeholder", - "t3ChatWebCookieHint": "Mở t3.chat → DevTools → Ứng dụng → Bộ nhớ cục bộ → https://t3.chat, sao chép 'convex-session-id'. Sau đó mở DevTools → Network, sao chép toàn bộ tiêu đề Cookie từ bất kỳ yêu cầu trò chuyện nào. Dán cả hai giá trị vào các trường bên dưới.", - "t3ChatWebCookiePlaceholder": "lồi-session-id=abc123...", - "blockClaudeExtraUsageDescription": "Block Claude Extra Usage Description", - "blockClaudeExtraUsageLabel": "Block Claude Extra Usage Label", - "bulkPasteAdded": "{count, plural, one {1 key added} other {# keys added}}", - "bulkPasteDuplicatesIgnored": "{count, plural, one {1 duplicate skipped} other {# duplicates skipped}}", - "bulkPasteHint": "Paste one API key per line. Empty lines are ignored and duplicate keys are skipped.", - "ccCompatibleBaseUrlHint": "Cc Compatible Base Url Hint", - "ccCompatibleBaseUrlPlaceholder": "Cc Compatible Base Url Placeholder", - "ccCompatibleChatPathHint": "Cc Compatible Chat Path Hint", - "ccCompatibleContext1mDescription": "Cc Compatible Context1M Description", - "ccCompatibleContext1mLabel": "Cc Compatible Context1M Label", - "ccCompatibleRedactThinkingDescription": "Adds the redact-thinking beta header for CC Compatible upstreams that require hidden Claude thinking streams.", - "ccCompatibleRedactThinkingLabel": "Enable redact-thinking beta", - "ccCompatibleSummarizeThinkingDescription": "Adds `display: \"summarized\"` to CC Compatible thinking requests so supported Claude models stream visible thinking deltas.", - "ccCompatibleSummarizeThinkingLabel": "Enable summarized thinking display", - "ccCompatibleDetailsTitle": "Cc Compatible Details Title", - "ccCompatibleLabel": "Cc Compatible Label", - "ccCompatibleModelsDescription": "Cc Compatible Models Description", - "ccCompatibleNameHint": "Cc Compatible Name Hint", - "ccCompatibleNamePlaceholder": "Cc Compatible Name Placeholder", - "ccCompatiblePrefixHint": "Cc Compatible Prefix Hint", - "ccCompatiblePrefixPlaceholder": "Cc Compatible Prefix Placeholder", - "ccCompatibleValidationHint": "Cc Compatible Validation Hint", - "claudeExtraUsageShort": "Claude Extra Usage Short", - "claudeExtraUsageToggleTitle": "Claude Extra Usage Toggle Title", - "codex5hToggleTitle": "Codex5H Toggle Title", - "codexFastServiceTierDescription": "Use the priority service tier for Codex requests when available.", - "codexFastServiceTierLabel": "Codex fast service tier", - "codexWeeklyToggleTitle": "Codex Weekly Toggle Title", - "compatUpstreamHeaderNamePlaceholder": "Compat Upstream Header Name Placeholder", - "compatUpstreamHeaderValuePlaceholder": "Compat Upstream Header Value Placeholder", - "compatible": "Compatible", - "configuredCount": "Configured Count", - "consoleApiKeyOracleHint": "Console Api Key Oracle Hint", - "consoleApiKeyOracleLabel": "Console Api Key Oracle Label", - "consoleApiKeyOraclePlaceholder": "Console Api Key Oracle Placeholder", + "blackboxWebCookieHint": "Gợi ý cookie web Blackbox", + "blackboxWebCookiePlaceholder": "Văn bản giữ chỗ cho cookie web Blackbox", + "t3ChatWebCookieHint": "Mở t3.chat → DevTools → Application → Local Storage → https://t3.chat, sao chép 'convex-session-id'. Sau đó mở DevTools → Network, sao chép toàn bộ tiêu đề Cookie từ bất kỳ yêu cầu chat nào. Dán cả hai giá trị vào các trường bên dưới.", + "t3ChatWebCookiePlaceholder": "convex-session-id=abc123...", + "blockClaudeExtraUsageDescription": "Ẩn các dòng mức sử dụng Claude bổ sung do một số nhà cung cấp báo cáo khi chúng trùng với việc tính token chính.", + "blockClaudeExtraUsageLabel": "Chặn các dòng dữ liệu sử dụng Claude bị trùng lặp", + "bulkPasteAdded": "{count, plural, one {Đã thêm 1 khóa} other {Đã thêm # khóa}}", + "bulkPasteDuplicatesIgnored": "{count, plural, one {Đã bỏ qua 1 khóa trùng lặp} other {Đã bỏ qua # khóa trùng lặp}}", + "bulkPasteHint": "Dán một khóa API trên mỗi dòng. Các dòng trống sẽ bị bỏ qua và các khóa trùng lặp sẽ bị bỏ qua.", + "ccCompatibleBaseUrlHint": "Base URL cho relay chỉ dành cho Claude Code. Không bao gồm /messages.", + "ccCompatibleBaseUrlPlaceholder": "https://relay.example.com/v1", + "ccCompatibleChatPathHint": "Mặc định là đường dẫn Messages API nghiêm ngặt của Claude Code. Chỉ thay đổi nếu tài liệu của relay chỉ định một đường dẫn khác.", + "ccCompatibleContext1mDescription": "Thêm header beta context-1m khi mô hình Claude được chọn hỗ trợ tính năng này.", + "ccCompatibleContext1mLabel": "Bật tính năng beta ngữ cảnh 1M", + "ccCompatibleRedactThinkingDescription": "Thêm header beta redact-thinking cho các nguồn CC Compatible yêu cầu ẩn luồng suy luận của Claude.", + "ccCompatibleRedactThinkingLabel": "Bật beta redact-thinking", + "ccCompatibleSummarizeThinkingDescription": "Thêm `display: \"summarized\"` vào các yêu cầu suy luận CC Compatible để các mô hình Claude được hỗ trợ truyền trực tuyến các phần suy luận cập nhật hiển thị.", + "ccCompatibleSummarizeThinkingLabel": "Bật hiển thị suy luận tóm tắt", + "ccCompatibleDetailsTitle": "Chi tiết relay tương thích với CC", + "ccCompatibleLabel": "Tương thích CC", + "ccCompatibleModelsDescription": "Các relay tương thích với CC không hiển thị danh sách mô hình. Hãy thêm ID mô hình Claude mà relay của bạn chấp nhận.", + "ccCompatibleNameHint": "Tên hiển thị cho relay chỉ dành riêng cho Claude Code này.", + "ccCompatibleNamePlaceholder": "CC Relay Production", + "ccCompatiblePrefixHint": "Được sử dụng trong các bí danh mô hình như prefix/model-id.", + "ccCompatiblePrefixPlaceholder": "cc", + "ccCompatibleValidationHint": "Chỉ sử dụng nhà cung cấp này cho các relay chỉ phục vụ máy khách Claude Code. OmniRoute sẽ chuyển đổi mọi yêu cầu đến sang định dạng truyền tải tương thích với Claude Code để các relay đó chấp nhận. Nếu bạn chỉ muốn sử dụng Claude Code CLI hoặc không chắc loại relay này có nghĩa là gì, hãy dùng nhà cung cấp tương thích Anthropic thông thường.", + "claudeExtraUsageShort": "Mức sử dụng bổ sung", + "claudeExtraUsageToggleTitle": "Chặn việc tính toán mức sử dụng bổ sung của Claude cho kết nối này", + "codex5hToggleTitle": "Theo dõi hạn mức 5 giờ của Codex cho kết nối này", + "codexFastServiceTierDescription": "Sử dụng gói dịch vụ ưu tiên cho các yêu cầu Codex khi có sẵn.", + "codexFastServiceTierLabel": "Tầng dịch vụ nhanh của Codex", + "codexWeeklyToggleTitle": "Theo dõi hạn mức hàng tuần của Codex cho kết nối này", + "compatUpstreamHeaderNamePlaceholder": "Gợi ý tên header upstream tương thích", + "compatUpstreamHeaderValuePlaceholder": "Gợi ý giá trị header upstream tương thích", + "compatible": "Tương thích", + "configuredCount": "Số lượng đã cấu hình", + "consoleApiKeyOracleHint": "Gợi ý API key Console Oracle", + "consoleApiKeyOracleLabel": "Nhãn API key Console Oracle", + "consoleApiKeyOraclePlaceholder": "Gợi ý nhập API key Console Oracle", "newApiUserIdLabel": "ID người dùng New-API", "newApiUserIdPlaceholder": "vd. 12345", "newApiUserIdHint": "Giá trị tiêu đề New-Api-User của AgentRouter, dùng cùng với khóa API console để lấy số dư hạn mức.", - "cpaModeDisabledTitle": "Cpa Mode Disabled Title", - "cpaModeEnabledTitle": "Cpa Mode Enabled Title", - "customUserAgentHint": "Custom User Agent Hint", - "customUserAgentLabel": "Custom User Agent Label", - "databricksBaseUrlHint": "Databricks Base Url Hint", - "defaultThinkingStrengthHint": "Used when a request does not specify reasoning effort.", - "defaultThinkingStrengthLabel": "Default thinking strength", - "deleteAllExtraApiKeys": "Delete all", - "excludedModelsHint": "Excluded Models Hint", - "excludedModelsLabel": "Excluded Models Label", - "excludedModelsPlaceholder": "Excluded Models Placeholder", - "expirationBannerExpired": "Expiration Banner Expired", - "expirationBannerExpiredDesc": "Expiration Banner Expired Desc", - "expirationBannerExpiringSoon": "Expiration Banner Expiring Soon", - "expirationBannerExpiringSoonDesc": "Expiration Banner Expiring Soon Desc", - "extraApiKeyMasked": "Key {index}: {prefix}••••{suffix}", - "extraApiKeysHint": "Extra Api Keys Hint", - "extraApiKeysLabel": "Extra Api Keys Label", - "apiKeyHealthLabel": "API Key Health", - "apiKeyStatusActive": "Active", - "apiKeyStatusWarning": "Warning ({count} failures)", - "apiKeyStatusInvalid": "Invalid", - "primaryKey": "Primary Key", - "apiKeyInvalidAlert": "{count} API key(s) marked as invalid due to authentication failures in connections: {connections}. They will be skipped in rotation. Click to review.", - "apiKeyInvalidAlertTitle": "API Key Health Alert", - "apiKeyWarningAlert": "{count} API key(s) in warning state due to elevated failure rate in connections: {connections}. Review to prevent rotation issues.", - "apiKeyWarningAlertTitle": "API Key Warning", - "googlePseInfo": "Google Pse Info", - "antigravityProjectIdHint": "Ghi đè tùy chọn cho các yêu cầu Mã đám mây chống trọng lực. Để trống để sử dụng dự án được phát hiện trong Google OAuth.", - "antigravityClientProfileLabel": "__MISSING__:Client profile", - "antigravityClientProfileHint": "__MISSING__:Choose which Antigravity client identity OmniRoute presents to the API.", - "antigravityClientProfileIde": "__MISSING__:IDE", - "antigravityClientProfileHarness": "__MISSING__:Harness / CLI", - "codexFastTierActiveChip": "__MISSING__:Codex Fast tier is active", - "tierFast": "__MISSING__:Fast", - "antigravityProjectIdLabel": "Mã dự án trên đám mây của Google", - "antigravityProjectIdPlaceholder": "my-gcp-dự án-id", - "grokWebCookieHint": "Grok Web Cookie Hint", - "grokWebCookiePlaceholder": "Grok Web Cookie Placeholder", - "herokuBaseUrlHint": "Heroku Base Url Hint", - "hideEmail": "Hide Email", - "imageProviders": "Image Providers", + "cpaModeDisabledTitle": "Chế độ tương thích CLIProxyAPI đã bị tắt", + "cpaModeEnabledTitle": "Chế độ tương thích CLIProxyAPI đã được bật", + "customUserAgentHint": "Gợi ý User Agent tùy chỉnh", + "customUserAgentLabel": "Nhãn User Agent tùy chỉnh", + "databricksBaseUrlHint": "Gợi ý URL cơ sở của Databricks", + "defaultThinkingStrengthHint": "Được sử dụng khi một yêu cầu không chỉ định mức độ suy luận.", + "defaultThinkingStrengthLabel": "Mức độ suy luận mặc định", + "deleteAllExtraApiKeys": "Xóa tất cả", + "excludedModelsHint": "Gợi ý các mô hình bị loại trừ", + "excludedModelsLabel": "Nhãn các mô hình bị loại trừ", + "excludedModelsPlaceholder": "Nhập các mô hình bị loại trừ", + "expirationBannerExpired": "Biểu ngữ đã hết hạn", + "expirationBannerExpiredDesc": "Mô tả biểu ngữ đã hết hạn", + "expirationBannerExpiringSoon": "Biểu ngữ sắp hết hạn", + "expirationBannerExpiringSoonDesc": "Mô tả biểu ngữ sắp hết hạn", + "extraApiKeyMasked": "Khóa {index}: {prefix}••••{suffix}", + "extraApiKeysHint": "Gợi ý API key bổ sung", + "extraApiKeysLabel": "Nhãn các API key bổ sung", + "apiKeyHealthLabel": "Tình trạng API key", + "apiKeyStatusActive": "Hoạt động", + "apiKeyStatusWarning": "Cảnh báo ({count} lần thất bại)", + "apiKeyStatusInvalid": "Không hợp lệ", + "primaryKey": "Khóa chính", + "apiKeyInvalidAlert": "{count} API key bị đánh dấu là không hợp lệ do lỗi xác thực trong các kết nối: {connections}. Chúng sẽ bị bỏ qua khi luân chuyển. Nhấp để xem lại.", + "apiKeyInvalidAlertTitle": "Cảnh báo sức khỏe API key", + "apiKeyWarningAlert": "{count} API key ở trạng thái cảnh báo do tỷ lệ lỗi tăng cao trong các kết nối: {connections}. Vui lòng xem xét để ngăn ngừa sự cố luân chuyển.", + "apiKeyWarningAlertTitle": "Cảnh báo API key", + "googlePseInfo": "Thông tin Google Pse", + "antigravityProjectIdHint": "Ghi đè tùy chọn cho các yêu cầu Antigravity Cloud Code. Để trống để sử dụng dự án được phát hiện trong quá trình Google OAuth.", + "antigravityClientProfileLabel": "Hồ sơ ứng dụng khách", + "antigravityClientProfileHint": "Chọn danh tính ứng dụng khách Antigravity mà OmniRoute sẽ sử dụng khi kết nối với API.", + "antigravityClientProfileIde": "IDE", + "antigravityClientProfileHarness": "Harness / CLI", + "codexFastTierActiveChip": "Gói Codex Fast đang hoạt động", + "tierFast": "Nhanh", + "antigravityProjectIdLabel": "Google Cloud Project ID", + "antigravityProjectIdPlaceholder": "my-gcp-project-id", + "grokWebCookieHint": "Gợi ý Grok Web Cookie", + "grokWebCookiePlaceholder": "Gợi ý nhập Grok Web Cookie", + "herokuBaseUrlHint": "Gợi ý Heroku Base URL", + "hideEmail": "Ẩn email", + "imageProviders": "Nhà cung cấp hình ảnh", "videoProviders": "Tạo video", "embeddingRerankProviders": "Nhúng & xếp hạng lại", - "imagesShortLabel": "Images Short Label", - "llmProviders": "Llm Providers", - "localProviderApiKeyOptionalHint": "Local Provider Api Key Optional Hint", - "localProviderBaseUrlHint": "Local Provider Base Url Hint", - "localProviders": "Local Providers", - "maxConcurrentWholeNumberError": "Max Concurrent Whole Number Error", - "museSparkWebCookieHint": "Muse Spark Web Cookie Hint", - "museSparkWebCookiePlaceholder": "Muse Spark Web Cookie Placeholder", - "oauth": "Oauth", - "openCliTools": "Open Cli Tools", - "openSettings": "Open Settings", - "openaiResponsesStoreDescription": "Allow compatible Responses API requests to preserve stored response state.", - "openaiResponsesStoreLabel": "OpenAI Responses store", - "perplexitySearchSharedKeyInfo": "Perplexity Search Shared Key Info", - "perplexityWebCookieHint": "Perplexity Web Cookie Hint", - "perplexityWebCookiePlaceholder": "Perplexity Web Cookie Placeholder", - "personalAccessTokenLabel": "Personal Access Token Label", - "qoderPatHint": "Qoder Pat Hint", - "qoderPatPlaceholder": "Qoder Pat Placeholder", - "refreshOauthTokenTitle": "Refresh Oauth Token Title", - "regionHint": "Region Hint", - "regionLabel": "Region Label", - "removeThisKey": "Remove This Key", - "routingTagsHint": "Routing Tags Hint", - "routingTagsLabel": "Routing Tags Label", - "routingTagsPlaceholder": "Routing Tags Placeholder", - "search": "Search", - "searchEngineIdHint": "Search Engine Id Hint", - "searchEngineIdLabel": "Search Engine Id Label", - "searchEngineIdRequired": "Search Engine Id Required", - "searchProvider": "Search Provider", - "searchProviderDesc": "Search Provider Desc", - "searchProviders": "Tìm kiếm nhà cung cấp...", - "searchProvidersHeading": "Search Providers Heading", - "searxngBaseUrlHint": "Searxng Base Url Hint", - "searxngInfo": "Searxng Info", - "sessionCookieLabel": "Session Cookie Label", - "showEmail": "Show Email", - "snowflakeBaseUrlHint": "Snowflake Base Url Hint", - "supportedEndpointAudio": "Supported Endpoint Audio", - "supportedEndpointChat": "Supported Endpoint Chat", - "supportedEndpointEmbeddings": "Supported Endpoint Embeddings", - "supportedEndpointImages": "Supported Endpoint Images", - "supportedEndpointsLabel": "Supported Endpoints Label", - "tagGroupHint": "Tag Group Hint", - "tagGroupLabel": "Tag Group Label", - "tagGroupPlaceholder": "Tag Group Placeholder", - "testModel": "Test Model", - "testingModel": "Testing Model", - "toggleOffShort": "Toggle Off Short", - "toggleOnShort": "Toggle On Short", - "tokenExpiredBadge": "Token Expired Badge", - "tokenExpiredTitle": "Token Expired Title", - "tokenExpiresSoonTitle": "Token Expires Soon Title", - "tokenShort": "Token Short", - "totalKeysRotating": "{count, plural, one {1 key rotating} other {# keys rotating}}", - "unhideModel": "Unhide Model", - "upstreamProxyProviders": "Upstream Proxy Providers", - "validationModelIdHint": "Validation Model Id Hint", - "validationModelIdLabel": "Validation Model Id Label", - "validationModelIdPlaceholder": "Validation Model Id Placeholder", - "vertexServiceAccountPlaceholder": "Paste your Service Account JSON ({\"type\":\"service_account\",\"project_id\":\"…\",\"client_email\":\"…\",\"private_key\":\"…\"}) or an OAuth access_token", - "webCookieProviders": "Web Cookie Providers", - "weeklyShort": "Weekly Short", - "xiaomiMimoBaseUrlHint": "Xiaomi Mimo Base Url Hint", - "zedImportButton": "Zed Import Button", - "zedImportFailed": "Zed Import Failed", - "zedImportHint": "Zed Import Hint", - "zedImportNetworkError": "Zed Import Network Error", - "zedImportNone": "Zed Import None", + "imagesShortLabel": "Nhãn ngắn cho hình ảnh", + "llmProviders": "Nhà cung cấp LLM", + "localProviderApiKeyOptionalHint": "Gợi ý tùy chọn API key của nhà cung cấp cục bộ", + "localProviderBaseUrlHint": "Gợi ý URL cơ sở của nhà cung cấp cục bộ", + "localProviders": "Nhà cung cấp cục bộ", + "maxConcurrentWholeNumberError": "Lỗi số nguyên cho số lượng đồng thời tối đa", + "museSparkWebCookieHint": "Gợi ý cookie web Muse Spark", + "museSparkWebCookiePlaceholder": "Trình giữ chỗ cookie web Muse Spark", + "oauth": "OAuth", + "openCliTools": "Mở công cụ CLI", + "openSettings": "Mở cài đặt", + "openaiResponsesStoreDescription": "Cho phép các yêu cầu Responses API tương thích lưu giữ trạng thái phản hồi đã lưu.", + "openaiResponsesStoreLabel": "Kho lưu trữ Responses của OpenAI", + "perplexitySearchSharedKeyInfo": "Thông tin khóa chia sẻ Perplexity Search", + "perplexityWebCookieHint": "Gợi ý cookie web Perplexity", + "perplexityWebCookiePlaceholder": "Trình giữ chỗ cookie web Perplexity", + "personalAccessTokenLabel": "Mã truy cập cá nhân", + "qoderPatHint": "Dán mã truy cập cá nhân (PAT) Qoder của bạn. Tạo một mã trong Qoder → Cài đặt → Mã truy cập cá nhân.", + "qoderPatPlaceholder": "Mã truy cập cá nhân Qoder của bạn", + "refreshOauthTokenTitle": "Tiêu đề làm mới token OAuth", + "regionHint": "Gợi ý vùng", + "regionLabel": "Nhãn vùng", + "removeThisKey": "Xóa khóa này", + "routingTagsHint": "Gợi ý thẻ định tuyến", + "routingTagsLabel": "Nhãn thẻ định tuyến", + "routingTagsPlaceholder": "Nhập thẻ định tuyến...", + "search": "Tìm kiếm", + "searchEngineIdHint": "Gợi ý ID công cụ tìm kiếm", + "searchEngineIdLabel": "Nhãn ID công cụ tìm kiếm", + "searchEngineIdRequired": "Yêu cầu ID công cụ tìm kiếm", + "searchProvider": "Nhà cung cấp tìm kiếm", + "searchProviderDesc": "Mô tả nhà cung cấp tìm kiếm", + "searchProviders": "Các nhà cung cấp tìm kiếm", + "searchProvidersHeading": "Tiêu đề tìm kiếm nhà cung cấp", + "searxngBaseUrlHint": "Gợi ý URL cơ sở Searxng", + "searxngInfo": "Thông tin Searxng", + "sessionCookieLabel": "Nhãn cookie phiên", + "showEmail": "Hiển thị email", + "snowflakeBaseUrlHint": "Gợi ý URL cơ sở Snowflake", + "supportedEndpointAudio": "Âm thanh", + "supportedEndpointChat": "Trò chuyện", + "supportedEndpointEmbeddings": "Phần nhúng", + "supportedEndpointImages": "Hình ảnh", + "supportedEndpointsLabel": "Nhãn các endpoint được hỗ trợ", + "tagGroupHint": "Gợi ý nhóm thẻ", + "tagGroupLabel": "Nhãn nhóm thẻ", + "tagGroupPlaceholder": "Nhập nhóm thẻ...", + "testModel": "Kiểm tra mô hình", + "testingModel": "Đang kiểm tra mô hình", + "toggleOffShort": "Tắt", + "toggleOnShort": "Bật", + "tokenExpiredBadge": "Nhãn token đã hết hạn", + "tokenExpiredTitle": "Tiêu đề token đã hết hạn", + "tokenExpiresSoonTitle": "Tiêu đề token sắp hết hạn", + "tokenShort": "Token ngắn", + "totalKeysRotating": "{count, plural, one {1 khóa đang xoay vòng} other {# khóa đang xoay vòng}}", + "unhideModel": "Hiện mô hình", + "upstreamProxyProviders": "Nhà cung cấp proxy thượng nguồn", + "validationModelIdHint": "Mô hình được sử dụng để xác minh khóa API. Để trống để sử dụng mô hình khả dụng đầu tiên của nhà cung cấp.", + "validationModelIdLabel": "Mô hình xác thực", + "validationModelIdPlaceholder": "Ví dụ: meta-llama/llama-3.1-8b-instruct", + "vertexServiceAccountPlaceholder": "Dán JSON Tài khoản dịch vụ của bạn ({\"type\":\"service_account\",\"project_id\":\"…\",\"client_email\":\"…\",\"private_key\":\"…\"}) hoặc access_token OAuth", + "webCookieProviders": "Nhà cung cấp Web Cookie", + "weeklyShort": "Hàng tuần", + "xiaomiMimoBaseUrlHint": "Gợi ý URL cơ sở Xiaomi Mimo", + "zedImportButton": "Nhập từ Zed", + "zedImportFailed": "Không thể nhập từ Zed", + "zedImportHint": "Gợi ý nhập từ Zed", + "zedImportNetworkError": "Lỗi mạng khi nhập từ Zed", + "zedImportNone": "Không có dữ liệu nhập từ Zed", "zedImportSuccess": "Zed Import Success", - "zedImporting": "Zed Importing", - "freeTierProviders": "Nhà cung cấp bậc miễn phí", - "freeTierLabel": "Cấp miễn phí có sẵn", - "freeTierProvidersDesc": "Các nhà cung cấp có cấp độ miễn phí — một số yêu cầu đăng ký khóa API, một số khác không cần thông tin xác thực nào cả.", + "zedImporting": "Đang nhập…", + "freeTierProviders": "Nhà cung cấp có gói miễn phí", + "freeTierLabel": "Có gói miễn phí", + "freeTierProvidersDesc": "Các nhà cung cấp có gói miễn phí — một số yêu cầu đăng ký khóa API, số khác hoàn toàn không cần thông tin xác thực.", "providerSummaryAll": "Tổng cộng", "ideProviders": "Nhà cung cấp IDE", - "ideProvidersDesc": "Biên tập viên có đăng ký AI tích hợp. Sử dụng trang nhà cung cấp để nhập thông tin xác thực trực tiếp từ chuỗi khóa IDE.", + "ideProvidersDesc": "Các trình soạn thảo có sẵn gói đăng ký AI. Sử dụng trang nhà cung cấp để nhập trực tiếp thông tin xác thực từ chùm khóa của IDE.", "noIdeProviders": "Không có nhà cung cấp IDE nào phù hợp với các bộ lọc hiện tại.", - "providerDetailFastTierTooltip": "Áp dụng cấp độ Codex Fast cho tất cả các kết nối Codex theo mặc định", + "providerDetailFastTierTooltip": "Áp dụng gói Codex Fast cho tất cả kết nối Codex theo mặc định", "providerDetailFastDefaultLabel": "Mặc định nhanh", "providerDetailBrowserManualConnect": "Kết nối trình duyệt/thủ công", "providerDetailAuthUrl": "URL xác thực", "providerDetailCallbackUrl": "URL gọi lại", "providerDetailValidClaudeCredentialsFile": "Tệp thông tin xác thực Claude hợp lệ", - "providerDetailPathAutoDetectedAllOs": "Đường dẫn được tự động phát hiện trên mỗi hệ điều hành (Linux/Mac/Windows).", + "providerDetailPathAutoDetectedAllOs": "Đường dẫn được tự động phát hiện cho từng hệ điều hành (Linux/Mac/Windows).", "providerDetailMyClaudeAccountPlaceholder": "Tài khoản Claude của tôi", - "providerDetailPathAutoDetected": "Đường dẫn được tự động phát hiện trên mỗi hệ điều hành (Linux/Mac).", - "webFetch": "__MISSING__:Web Fetch", - "webFetchTooltip": "__MISSING__:Providers that extract content from web URLs (HTML → Markdown, scrape, screenshot)", - "webFetchProvidersHeading": "__MISSING__:Web Fetch Providers", - "compatibleProvidersDesc": "__MISSING__:OpenAI-compatible and Anthropic-compatible endpoints you host or configure. Point any OpenAI SDK to your own URL and route requests here.", - "oauthProvidersDesc": "__MISSING__:Providers authenticated via OAuth — sign in once and OmniRoute handles token rotation automatically.", - "webCookieProvidersDesc": "Các nhà cung cấp này sử dụng phiên web của trình duyệt, cookie hoặc mã thông báo web thay vì khóa API. Mở một nhà cung cấp để thêm thông tin xác thực phiên được yêu cầu.", - "apiKeyProvidersDesc": "__MISSING__:Standard API key providers. Add your key once and OmniRoute routes, retries, and rate-limits on your behalf.", - "noAuthProvidersDesc": "__MISSING__:Open endpoints that require no credentials — ready to use immediately without any sign-up.", - "upstreamProxyProvidersDesc": "__MISSING__:Route outbound traffic through an upstream proxy before it reaches the provider. Useful for corporate networks or traffic inspection.", - "webFetchProvidersDesc": "__MISSING__:Providers that fetch and extract content from web URLs. Use them to ground prompts with live web data.", - "aggregatorsGatewaysDesc": "__MISSING__:Multi-provider aggregators and AI gateways that expose a single unified API across dozens of underlying models.", - "enterpriseCloudDesc": "__MISSING__:Enterprise-tier and cloud-hosted models with enhanced SLAs, compliance certifications, and dedicated capacity.", - "cloudAgentProvidersDesc": "__MISSING__:Autonomous cloud agents that execute long-running tasks with plan approval and live status tracking.", - "localProvidersDesc": "__MISSING__:Self-hosted models running on your own hardware. No data leaves your infrastructure.", - "searchProvidersDesc": "__MISSING__:Web and document search providers. Attach them to LLM calls for Retrieval-Augmented Generation.", - "audioProvidersDesc": "__MISSING__:Text-to-speech and speech-to-text providers for voice I/O and audio transcription pipelines.", - "embeddingRerankProvidersDesc": "__MISSING__:Vector embedding and reranking providers for semantic search, RAG pipelines, and similarity scoring.", - "imageProvidersDesc": "__MISSING__:Image generation and vision providers — create images from text or analyse existing ones.", - "videoProvidersDesc": "__MISSING__:Video generation providers. Create short video clips from text prompts or images.", - "onboardingWizard": "Trình hướng dẫn giới thiệu nhà cung cấp", - "onboardingWizardShort": "Trình hướng dẫn giới thiệu", - "onboardingWizardDescription": "Kết nối khóa API, nhà cung cấp tương thích tùy chỉnh và OAuth bằng tính năng xác thực, tính bền vững và kiểm tra kết nối ngay lập tức.", - "onboardingStepType": "loại", - "onboardingStepProvider": "nhà cung cấp", + "providerDetailPathAutoDetected": "Đường dẫn được tự động phát hiện cho từng hệ điều hành (Linux/Mac).", + "webFetch": "Thu thập dữ liệu web", + "webFetchTooltip": "Các nhà cung cấp trích xuất nội dung từ URL web (HTML → Markdown, cào dữ liệu, chụp ảnh màn hình)", + "webFetchProvidersHeading": "Nhà cung cấp thu thập dữ liệu web", + "compatibleProvidersDesc": "Các endpoint tương thích với OpenAI và tương thích với Anthropic do bạn tự lưu trữ hoặc cấu hình. Trỏ bất kỳ SDK OpenAI nào tới URL của riêng bạn và định tuyến các yêu cầu tại đây.", + "oauthProvidersDesc": "Các nhà cung cấp được xác thực qua OAuth — đăng nhập một lần và OmniRoute sẽ tự động xử lý việc xoay vòng token.", + "webCookieProvidersDesc": "Các nhà cung cấp này sử dụng phiên web của trình duyệt, cookie hoặc token web thay vì khóa API. Mở một nhà cung cấp để thêm thông tin xác thực phiên được yêu cầu.", + "apiKeyProvidersDesc": "Các nhà cung cấp khóa API tiêu chuẩn. Thêm khóa của bạn một lần và OmniRoute sẽ thay mặt bạn định tuyến, thử lại và giới hạn tốc độ.", + "noAuthProvidersDesc": "Các endpoint mở không yêu cầu thông tin xác thực — sẵn sàng sử dụng ngay lập tức mà không cần đăng ký.", + "upstreamProxyProvidersDesc": "Định tuyến lưu lượng truy cập đi qua một proxy ngược dòng trước khi đến nhà cung cấp. Hữu ích cho mạng doanh nghiệp hoặc kiểm tra lưu lượng truy cập.", + "webFetchProvidersDesc": "Các nhà cung cấp thu thập và trích xuất nội dung từ các URL web. Sử dụng chúng để cung cấp thông tin thực tế cho prompt bằng dữ liệu web trực tiếp.", + "aggregatorsGatewaysDesc": "Các bộ tổng hợp đa nhà cung cấp và cổng AI cung cấp một API thống nhất cho hàng chục mô hình cơ sở.", + "enterpriseCloudDesc": "Các mô hình cấp doanh nghiệp và được lưu trữ trên đám mây với các cam kết dịch vụ (SLA) nâng cao, chứng nhận tuân thủ và dung lượng chuyên dụng.", + "cloudAgentProvidersDesc": "Các tác nhân đám mây tự chủ thực hiện các tác vụ chạy lâu dài với sự phê duyệt kế hoạch và theo dõi trạng thái trực tiếp.", + "localProvidersDesc": "Các mô hình tự lưu trữ chạy trên phần cứng của riêng bạn. Không có dữ liệu nào rời khỏi cơ sở hạ tầng của bạn.", + "searchProvidersDesc": "Các nhà cung cấp tìm kiếm web và tài liệu. Đính kèm chúng vào các lệnh gọi LLM để phục vụ Tạo sinh tăng cường truy xuất (RAG).", + "audioProvidersDesc": "Các nhà cung cấp chuyển văn bản thành giọng nói và chuyển giọng nói thành văn bản cho đầu vào/đầu ra giọng nói và luồng xử lý phiên âm âm thanh.", + "embeddingRerankProvidersDesc": "Các nhà cung cấp nhúng vector và xếp hạng lại (reranking) cho tìm kiếm ngữ nghĩa, luồng xử lý RAG và tính điểm tương đồng.", + "imageProvidersDesc": "Các nhà cung cấp tạo hình ảnh và thị giác máy tính — tạo hình ảnh từ văn bản hoặc phân tích hình ảnh hiện có.", + "videoProvidersDesc": "Các nhà cung cấp tạo video. Tạo các đoạn video ngắn từ prompt văn bản hoặc hình ảnh.", + "onboardingWizard": "Trình hướng dẫn thiết lập nhà cung cấp", + "onboardingWizardShort": "Trình hướng dẫn thiết lập", + "onboardingWizardDescription": "Kết nối các nhà cung cấp dùng khóa API, tương thích tùy chỉnh và OAuth với tính năng xác thực, lưu trữ và kiểm tra kết nối ngay lập tức.", + "onboardingStepType": "Loại", + "onboardingStepProvider": "Nhà cung cấp", "onboardingStepCredentials": "Thông tin xác thực", - "onboardingStepResult": "kết quả", + "onboardingStepResult": "Kết quả", "onboardingTypeApiKeyTitle": "Nhà cung cấp khóa API", - "onboardingTypeApiKeyText": "Sử dụng các nhà cung cấp tích hợp sẵn như OpenAI, Anthropic, Gemini, Groq, Azure, v.v.", + "onboardingTypeApiKeyText": "Sử dụng các nhà cung cấp tích hợp sẵn như OpenAI, Anthropic, Gemini, Groq, Azure và nhiều nhà cung cấp khác.", "onboardingTypeCustomTitle": "Nhà cung cấp tương thích tùy chỉnh", - "onboardingTypeCustomText": "Tạo điểm cuối tương thích với OpenAI-, Anthropic- hoặc Claude Code và thêm khóa của nó.", + "onboardingTypeCustomText": "Tạo một endpoint tương thích với OpenAI, Anthropic hoặc Claude Code và thêm khóa của endpoint đó.", "onboardingTypeOAuthTitle": "Nhà cung cấp OAuth", - "onboardingTypeOAuthText": "Sử dụng lại các luồng nhập cục bộ, mã thiết bị hoặc OAuth hiện có cho các nhà cung cấp mã hóa.", - "onboardingChooseOAuthProvider": "Chọn nhà cung cấp OAuth", - "onboardingChooseApiKeyProvider": "Chọn nhà cung cấp khóa API", - "onboardingChooseProviderDescription": "Chọn một nhà cung cấp, sau đó trình hướng dẫn sẽ hướng dẫn bạn thông qua thông tin xác thực và kiểm tra.", + "onboardingTypeOAuthText": "Sử dụng lại các luồng OAuth, mã thiết bị hoặc nhập cục bộ hiện có cho các nhà cung cấp lập trình.", + "onboardingChooseOAuthProvider": "Chọn một nhà cung cấp OAuth", + "onboardingChooseApiKeyProvider": "Chọn một nhà cung cấp dùng khóa API", + "onboardingChooseProviderDescription": "Chọn một nhà cung cấp, sau đó trình hướng dẫn sẽ hướng dẫn bạn qua các bước thiết lập thông tin xác thực và kiểm tra.", "onboardingChangeType": "Thay đổi loại", "onboardingChangeProvider": "Thay đổi nhà cung cấp", "onboardingSearchProviders": "Tìm kiếm nhà cung cấp…", "onboardingApiKeyOptional": "Khóa API tùy chọn", "onboardingProviderConnected": "Đã kết nối nhà cung cấp", - "onboardingProviderSavedWithWarnings": "Đã lưu nhà cung cấp kèm theo cảnh báo", - "onboardingProviderFinished": "Quá trình giới thiệu nhà cung cấp đã hoàn tất", + "onboardingProviderSavedWithWarnings": "Đã lưu nhà cung cấp với các cảnh báo", + "onboardingProviderFinished": "Hoàn tất thiết lập nhà cung cấp", "onboardingYourProviderConnection": "Kết nối nhà cung cấp của bạn", - "onboardingTestPassed": "Đã vượt qua bài kiểm tra", - "onboardingTestFailed": "Kiểm tra không thành công", + "onboardingTestPassed": "Kiểm tra thành công", + "onboardingTestFailed": "Kiểm tra thất bại", "onboardingOpenProviderDetails": "Mở chi tiết nhà cung cấp", - "onboardingTryInPlayground": "Hãy thử ở sân chơi", + "onboardingTryInPlayground": "Thử trong môi trường thử nghiệm", "onboardingDefaultConnectionName": "{provider} Chính", - "onboardingTestingConnection": "Đang kiểm tra kết nối của nhà cung cấp…", + "onboardingTestingConnection": "Đang kiểm tra kết nối nhà cung cấp…", "onboardingValidatingCredentials": "Đang xác thực thông tin xác thực…", "onboardingSavingConnection": "Đang lưu kết nối nhà cung cấp…", - "onboardingProviderFailed": "Việc giới thiệu nhà cung cấp không thành công", + "onboardingProviderFailed": "Thiết lập nhà cung cấp thất bại", "onboardingCreatingCompatibleProvider": "Đang tạo nhà cung cấp tương thích…", - "onboardingSavingCompatibleConnection": "Đang lưu kết nối của nhà cung cấp tương thích…", + "onboardingSavingCompatibleConnection": "Đang lưu kết nối nhà cung cấp tương thích…", "onboardingCustomProviderFallbackName": "Nhà cung cấp tùy chỉnh", - "onboardingCustomProviderFailed": "Việc giới thiệu nhà cung cấp tùy chỉnh không thành công", + "onboardingCustomProviderFailed": "Thiết lập nhà cung cấp tùy chỉnh thất bại", "onboardingLoadingOAuthConnection": "Đang tải kết nối OAuth…", - "onboardingOAuthNoConnectionFound": "OAuth đã hoàn tất nhưng không tìm thấy kết nối nhà cung cấp nào.", - "onboardingOAuthFailed": "Việc giới thiệu OAuth không thành công", + "onboardingOAuthNoConnectionFound": "OAuth đã hoàn tất, nhưng không tìm thấy kết nối nhà cung cấp nào.", + "onboardingOAuthFailed": "Thiết lập OAuth thất bại", "onboardingAddProvider": "Thêm {provider}", "onboardingConnectionName": "Tên kết nối", "onboardingApiKeyOptionalLabel": "Khóa API (tùy chọn)", "onboardingBaseUrlOverride": "Ghi đè URL cơ sở", - "onboardingBaseUrlOverrideHint": "Tùy chọn. Được lưu trữ dưới dạng nhà cung cấpSpecificData.baseUrl.", - "onboardingRegion": "Vùng", - "onboardingSearchCx": "Tìm kiếm CX / Id động cơ", - "onboardingProviderSpecificIdPlaceholder": "Id cụ thể của nhà cung cấp tùy chọn", - "onboardingCustomUserAgent": "Tác nhân người dùng tùy chỉnh", - "onboardingWorking": "Đang làm việc…", + "onboardingBaseUrlOverrideHint": "Tùy chọn. Được lưu trữ dưới dạng providerSpecificData.baseUrl.", + "onboardingRegion": "Khu vực", + "onboardingSearchCx": "CX tìm kiếm / ID công cụ", + "onboardingProviderSpecificIdPlaceholder": "ID cụ thể của nhà cung cấp (tùy chọn)", + "onboardingCustomUserAgent": "User-Agent tùy chỉnh", + "onboardingWorking": "Đang xử lý…", "onboardingValidateSaveTest": "Xác thực, lưu và kiểm tra", "onboardingBack": "Quay lại", "onboardingCreateCustomCompatibleProvider": "Tạo nhà cung cấp tương thích tùy chỉnh", - "onboardingCreateCustomCompatibleDescription": "Trình hướng dẫn trước tiên tạo nút nhà cung cấp, sau đó lưu trữ và kiểm tra kết nối khóa API của nút đó.", + "onboardingCreateCustomCompatibleDescription": "Trình hướng dẫn trước tiên sẽ tạo một nút nhà cung cấp, sau đó lưu và kiểm tra kết nối bằng khóa API của nút đó.", "onboardingProtocol": "Giao thức", "onboardingOpenAiCompatible": "Tương thích OpenAI", - "onboardingAnthropicCompatible": "Tương thích với con người", - "onboardingClaudeCodeCompatible": "Tương thích mã Claude", + "onboardingAnthropicCompatible": "Tương thích Anthropic", + "onboardingClaudeCodeCompatible": "Tương thích Claude Code", "onboardingProviderPrefix": "Tiền tố nhà cung cấp", - "onboardingProviderPrefixHint": "Được sử dụng để tạo id nhà cung cấp được quản lý.", + "onboardingProviderPrefixHint": "Được sử dụng để tạo ID nhà cung cấp được quản lý.", "onboardingChatPath": "Đường dẫn trò chuyện", "onboardingModelsPath": "Đường dẫn mô hình", "onboardingCreateSaveTest": "Tạo, lưu và kiểm tra", @@ -4413,235 +4752,425 @@ "onboardingOAuthFlowDescription": "OmniRoute sẽ mở luồng OAuth hiện có cho nhà cung cấp này. Sau khi đăng nhập, trình hướng dẫn sẽ tải lại kết nối đã lưu và chạy kiểm tra kết nối tương tự như trang nhà cung cấp.", "onboardingStartOAuthFlow": "Bắt đầu luồng OAuth", "passthroughModelsDescription": "{provider} chấp nhận ID mô hình gốc của nhà cung cấp. Nhập từ /models hoặc thêm ID tùy chỉnh để định tuyến.", - "bedrockModelsDescription": "Các mô hình Amazon Bedrock được phân bổ theo khu vực AWS. Nhập từ /models hoặc thêm ID mô hình Bedrock được bật trong vùng đã chọn.", - "bedrockModelPlaceholder": "nhân chủng học.claude-sonnet-4-6", + "bedrockModelsDescription": "Các mô hình Amazon Bedrock được giới hạn theo vùng AWS. Nhập từ /models hoặc thêm ID mô hình Bedrock được bật trong vùng đã chọn.", + "bedrockModelPlaceholder": "anthropic.claude-sonnet-4-6", "addProviderSessionCookieTitle": "Thêm cookie phiên {provider}", - "addProviderWebTokenTitle": "Thêm mã thông báo web {provider}", + "addProviderWebTokenTitle": "Thêm token web {provider}", "addProviderConnectionTitle": "Thêm kết nối {provider}", - "webTokenCredentialLabel": "Mã thông báo phiên web", + "webTokenCredentialLabel": "Token phiên web", "webNoAuthCredentialLabel": "Không cần thông tin xác thực", "webCookieCredentialHint": "Cookie bắt buộc: {credential}. Dán giá trị tiêu đề Cookie từ phiên web {provider} đã đăng nhập của chính bạn. Không bao gồm tiền tố Cookie:.", - "webTokenCredentialHint": "Thông tin xác thực: {credential}. Dán giá trị mã thông báo từ phiên web {provider} đã đăng nhập của chính bạn hoặc xuất HAR DevTools nếu nhà cung cấp hỗ trợ.", + "webTokenCredentialHint": "Thông tin xác thực: {credential}. Dán giá trị token từ phiên web {provider} đã đăng nhập của chính bạn hoặc bản xuất HAR từ DevTools nếu nhà cung cấp hỗ trợ.", "webCookieEditHint": "Để trống để giữ cookie phiên hiện tại. Cookie bắt buộc: {credential}.", - "webTokenEditHint": "Để trống để giữ mã thông báo phiên web hiện tại. Thông tin xác thực: {credential}.", - "webSessionGuideTitle": "Cách nhận thông tin xác thực phiên", + "webTokenEditHint": "Để trống để giữ token phiên web hiện tại. Thông tin xác thực: {credential}.", + "webSessionGuideTitle": "Cách lấy thông tin xác thực phiên", "webSessionGuideIntro": "{provider} sử dụng phiên web của trình duyệt thay vì khóa API.", "webCookieRequiredCredential": "Cookie bắt buộc: {credential}", - "webTokenRequiredCredential": "Mã thông báo bắt buộc: {credential}", + "webTokenRequiredCredential": "Token bắt buộc: {credential}", "webSessionGuideStep1": "Đăng nhập vào {provider} trong trình duyệt của bạn.", - "webSessionGuideStep2": "Mở công cụ dành cho nhà phát triển trình duyệt và kiểm tra yêu cầu do ứng dụng web đưa ra.", - "webSessionGuideStep3": "Sao chép thông tin xác thực được yêu cầu từ miền riêng của nhà cung cấp. Đối với cookie, chỉ sao chép giá trị tiêu đề Cookie và bỏ qua Cookie:.", - "webSessionGuideStep4": "Dán nó vào đây và kiểm tra kết nối. Nếu nó ngừng hoạt động, hãy đăng nhập lại và thay thế bằng một giá trị mới.", - "webSessionSecurityHint": "Hãy coi đây như một mật khẩu: nó có thể truy cập vào tài khoản web đã đăng nhập của bạn cho đến khi hết hạn hoặc bị thu hồi.", - "webNoAuthGuideTitle": "Không cần thông tin xác thực", - "webNoAuthGuideBody": "{provider} không cần khóa API hoặc cookie. Lưu kết nối để sử dụng điểm cuối web miễn phí của nó.", - "webSessionCredentialValidationFailed": "Xác thực thông tin xác thực phiên không thành công. Đăng nhập lại, sao chép thông tin xác thực mới và thử lại.", + "webSessionGuideStep2": "Mở công cụ dành cho nhà phát triển của trình duyệt và kiểm tra một yêu cầu do ứng dụng web gửi.", + "webSessionGuideStep3": "Sao chép thông tin xác thực được yêu cầu từ tên miền riêng của nhà cung cấp. Đối với cookie, chỉ sao chép giá trị tiêu đề Cookie và bỏ qua Cookie:.", + "webSessionGuideStep4": "Dán vào đây và kiểm tra kết nối. Nếu nó ngừng hoạt động, hãy đăng nhập lại và thay thế bằng một giá trị mới.", + "webSessionSecurityHint": "Hãy coi đây như mật khẩu: nó có thể truy cập vào tài khoản web đã đăng nhập của bạn cho đến khi hết hạn hoặc bị thu hồi.", + "webNoAuthGuideTitle": "Không yêu cầu thông tin xác thực", + "webNoAuthGuideBody": "{provider} không cần khóa API hoặc cookie. Lưu kết nối để sử dụng endpoint web miễn phí của nó.", + "webSessionCredentialValidationFailed": "Xác thực thông tin xác thực phiên thất bại. Hãy đăng nhập lại, sao chép thông tin xác thực mới và thử lại.", "checkCookie": "Kiểm tra cookie", - "checkWebToken": "Kiểm tra mã thông báo", + "checkWebToken": "Kiểm tra token", "filterAll": "Tất cả", "filterActive": "Hoạt động", "filterError": "Lỗi", "filterBanned": "Bị cấm", "filterCreditsExhausted": "Hết tín dụng", - "contextWindowOverrideLabel": "__MISSING__:Context Window Override", - "contextWindowOverridePlaceholder": "__MISSING__:e.g. 131072", - "contextWindowOverrideHint": "__MISSING__:Manually set this model's real context window (tokens) when the provider misreports it. Wins over auto-detected/catalog values and prevents combo routing from dropping the model.", - "contextWindowOverrideInvalid": "__MISSING__:Context window override must be a positive whole number of tokens", - "visionCapableLabel": "__MISSING__:Vision capable", - "visionCapableHint": "__MISSING__:Manually flag this model as vision-capable when the provider's discovery metadata doesn't report an image input modality (common for self-hosted/local backends).", + "contextWindowOverrideLabel": "Ghi đè cửa sổ ngữ cảnh", + "contextWindowOverridePlaceholder": "Ví dụ: 131072", + "contextWindowOverrideHint": "Đặt thủ công cửa sổ ngữ cảnh thực tế của mô hình (token) khi nhà cung cấp báo sai. Giá trị này được ưu tiên hơn giá trị tự động phát hiện hoặc danh mục và ngăn định tuyến combo loại bỏ mô hình.", + "contextWindowOverrideInvalid": "Giá trị ghi đè cửa sổ ngữ cảnh phải là số token nguyên dương", + "visionCapableLabel": "Hỗ trợ thị giác", + "visionCapableHint": "Đánh dấu thủ công mô hình là có khả năng thị giác khi metadata khám phá của nhà cung cấp không báo phương thức đầu vào hình ảnh (thường gặp ở backend tự lưu trữ hoặc cục bộ).", "kimiOfficialSupporterBadge": "Official Supporter", - "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) is an official OmniRoute launch partner" + "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) is an official OmniRoute launch partner", + "Account Deactivated": "Account Deactivated", + "importFromFile": "Import from file", + "importFromFileTitle": "Import providers from file", + "importFromFileDescription": "Upload a CSV or JSON file listing multiple providers (each row can be a different provider type). Review the parsed rows below and pick which ones to import.", + "importFromFileChoose": "Choose file", + "importFromFileSelectHint": "{count} of {total} selected", + "importFromFileColProvider": "Provider", + "importFromFileColName": "Name", + "importFromFileColBaseUrl": "Base URL", + "importFromFileErrorLine": "Row {line}: {reason}", + "importErrorMissingProvider": "missing provider", + "importErrorMissingName": "missing name", + "importErrorMissingApiKey": "missing API key", + "importErrorInvalidPriority": "invalid priority (must be 1-100)", + "importErrorMalformedRow": "malformed row", + "importErrorNotArray": "file must contain a JSON array", + "importFromFileImporting": "Importing…", + "importFromFileImport": "Import {count} providers", + "importFromFileResult": "Imported {success} providers ({failed} failed)", + "adaptaTutorial": { + "title": "How to connect Adapta Web", + "introPrefix": "Adapta authenticates through Clerk. The token", + "introSuffix": "is a long-lived JWT that lets OmniRoute refresh sessions automatically.", + "or": "or", + "step1Title": "Open Adapta chat", + "step1DescPrefix": "Open", + "step1DescSuffix": "and sign in with your Gold or Business account.", + "step2Title": "Open DevTools", + "step2DescPrefix": "Press", + "step2DescSuffix": "to open Developer Tools.", + "step3Title": "Go to Application → Cookies", + "step3DescPrefix": "In the", + "step3DescMiddle": "expand", + "step3DescSuffix": "and click", + "step4Title": "Copy the cookie value for", + "step4DescPrefix": "Find the cookie named", + "step4DescMiddle": "in the list. Click it and copy the content from the", + "step4DescSuffix": "column. It starts with", + "step5Title": "Paste it here and save", + "step5DescPrefix": "Click", + "step5DescMiddle": "paste the", + "step5DescSuffix": "value into the API Key field, then save. OmniRoute will refresh the session automatically.", + "tipLabel": "Tip:", + "tipPrefix": "The", + "tipSuffix": "cookie is long-lived, usually for months. You only need to renew it if you sign out or Adapta invalidates the session." + }, + "distributeProxies": "Distribute Proxies", + "distributing": "Distributing...", + "selectedCount": "{count, plural, one {# selected} other {# selected}}", + "accountsCount": "{count, plural, one {# account} other {# accounts}}", + "testAllModels": "Test all models", + "testAllModelsConfirm": "Test all visible models? Failed models will be hidden if auto-hide is enabled.", + "testingAllModels": "Testing {done}/{total}...", + "testAllResults": "{ok} of {total} models working", + "noModelsToTest": "No models match the current filter", + "showAllModels": "All", + "showVisibleOnly": "Visible only", + "freeFilterAll": "All", + "freeFilterFreeOnly": "Free only", + "freeFilterPaidOnly": "Paid only", + "sortFreeFirst": "Free first", + "showHiddenOnly": "Hidden only", + "filterByVisibility": "Filter by visibility", + "autoHideFailed": "Auto-hide failed models", + "autoHideFailedHint": "When enabled, Test all hides non-transient failures from public catalogs such as /v1/models. Single-model tests never auto-hide.", + "testAllCompleted": "Tested {total} models: {ok} OK, {failed} failed", + "modelAutoHidden": "Model {model} auto-hidden (test failed)", + "filterVisible": "Visible only", + "filterHidden": "Hidden only", + "modelsHiddenCount": "{count} hidden", + "iconUrlLabel": "Icon URL", + "iconUrlHint": "Optional. Image URL shown as this provider's icon.", + "batchDeleteConfirmTitle": "Delete connections", + "batchDeleteConfirmButton": "Delete", + "noFilteredConnections": "No connections match the current filter.", + "setAliasSuccess": "Alias {alias} set", + "deleteAliasSuccess": "Alias {alias} deleted", + "noFreeModelsFound": "No free models found for this provider — nothing imported.", + "fetchModelsSuccess": "Found {count} new models", + "fetchModelsFailed": "Could not auto-fetch models (you can retry from settings)", + "testAllRateLimited": "Rate limit reached, stopped early", + "hideFailedAuto": "Auto-hide failed models", + "hideAllModels": "Hide all", + "providerQuotaShort": "Quota", + "hideConnectionFromProviderQuota": "Hide this account from Provider Quota", + "showConnectionInProviderQuota": "Show this account in Provider Quota", + "quotaVisibilityUpdateFailed": "Failed to update Provider Quota visibility", + "testAllProgress": "Tested {done}/{total}", + "testAllFailedHidden": "{count} failed models hidden", + "testAllDone": "All models tested", + "compatibleDefaultModelLabel": "Default Model", + "compatibleDefaultModelHint": "Enter the model ID exactly as your compatible endpoint expects it. This model will be saved as the connection default.", + "errorTypeCreditsExhausted": "No credits", + "errorTypeBanned": "403 Banned", + "proxyOn": "Proxy On", + "proxyOff": "Direct (bypass proxy)", + "proxyEnabledTitle": "Proxy is enabled for this connection", + "proxyDisabledTitle": "Direct connection — bypasses every proxy (including the global proxy) for this connection", + "perKeyProxyOn": "Per-key", + "perKeyProxyOff": "Connection", + "perKeyProxyEnabledTitle": "Per-key proxy assignment enabled for this provider", + "perKeyProxyDisabledTitle": "Per-key proxy assignment disabled for this provider", + "targetFormatLabel": "Target Format", + "targetFormatHint": "Override the upstream wire format. Use 'Anthropic Messages' to route OpenAI-compatible providers (e.g. opencode-go) through the /v1/messages endpoint.", + "targetFormatAuto": "Default (auto)", + "targetFormatGemini": "Gemini", + "targetFormatAntigravity": "Antigravity", + "compatParamFiltersLabel": "Param Filters", + "compatBlockedParamsHint": "Blocked params (stripped from requests)", + "compatAllowedParamsHint": "Allowed params (re-added after deny)", + "paramFiltersSectionTitle": "Param Filters", + "paramFiltersSectionHint": "Strip or re-add request parameters before sending to this provider. Used to avoid 400 errors from providers that reject certain params (e.g. NVIDIA NIM rejects thinking).", + "paramFiltersBlockedLabel": "Blocked parameters", + "paramFiltersBlockedHint": "These params are stripped from outgoing requests (denylist).", + "paramFiltersAllowedLabel": "Allowed parameters", + "paramFiltersAllowedHint": "These params are re-added after denylist stripping (only if the client sent them).", + "paramFiltersAutoLearnLabel": "Auto-learn from 400 errors", + "paramFiltersAutoLearnHint": "When enabled, if the upstream returns a 400 with \"Unsupported parameter: X\", the param is automatically added to the block list and the request retried.", + "paramFiltersSaving": "Saving…", + "paramFiltersSaveChanges": "Save Changes", + "paramFiltersResetToDefault": "Reset to Default", + "paramFiltersLoadError": "Failed to load param filter config: {error}", + "paramFiltersSaveSuccess": "Param filter config saved", + "paramFiltersSaveError": "Failed to save param filter config: {error}", + "paramFiltersResetSuccess": "Param filter config reset to defaults", + "paramFiltersResetError": "Failed to reset param filter config: {error}", + "interceptionSectionTitle": "Web Tool Interception", + "interceptionSectionHint": "Route this provider's native web_search / web_fetch tool calls through OmniRoute's own search and fetch endpoints instead of letting the provider run them natively. Off by default — existing behavior is unchanged.", + "interceptSearchLabel": "Intercept web_search", + "interceptSearchHint": "Rewrite native web_search tool calls to OmniRoute's /v1/search.", + "interceptFetchLabel": "Intercept web_fetch", + "interceptFetchHint": "Rewrite native web_fetch tool calls to OmniRoute's /v1/web/fetch.", + "interceptionLoadError": "Failed to load interception settings: {error}", + "interceptionSaveError": "Failed to save interception settings: {error}", + "importFreeModelsOnlyLabel": "Import only free models", + "importFreeModelsOnlyHint": "When enabled, only this provider's free models are imported. Paid models are skipped.", + "testModelIdLabel": "Model ID (optional)", + "testModelIdPlaceholder": "e.g. my-model-id", + "testModelIdHint": "If the provider lacks a /models endpoint, enter a model ID to validate via /chat/completions instead.", + "codexCliGuideButton": "Codex CLI Guide", + "codexCliGuideTitle": "Codex CLI Guide", + "codexCliGuideLoading": "Loading guide...", + "codexCliGuideLoadFailed": "Could not load the guide.", + "codexExternalLinkButton": "External Codex link", + "codexExternalLinkModalTitle": "External Codex link", + "codexExternalLinkModalDescription": "Share this single-use link with the person who will authenticate the Codex account. They open it in their own browser, complete the OpenAI login, and the connection is registered here. The link expires in 15 minutes.", + "codexExternalLinkGenerating": "Generating link...", + "codexExternalLinkWaiting": "Waiting for browser authentication. This window refreshes automatically.", + "codexExternalLinkCreateFailed": "Failed to generate the link.", + "codexExternalLinkNetworkError": "Could not contact the server.", + "codexExternalLinkConnected": "Codex account connected through the external link.", + "codexExternalLinkExpired": "The link expired before completion.", + "clientIdentityLabel": "Client Identity", + "clientIdentityHint": "Optional. Adds client fingerprint headers (e.g. User-Agent) matching a known CLI for compatible gateways that expect one.", + "disableCoolingDescription": "Skip the transient cooldown so this connection stays eligible even after recoverable errors (terminal states like banned/expired still apply).", + "disableCoolingLabel": "Disable cooldown for this connection", + "m365TierLabel": "Copilot tier", + "m365TierHint": "Choose which Microsoft 365 Copilot surface this connection uses. Individual is the default consumer BizChat; Education and Enterprise (work) opt into their tenant surfaces.", + "m365TierIndividualOption": "Individual (default)", + "m365TierEduOption": "Education", + "m365TierEnterpriseOption": "Enterprise / Work", + "rateLimitOverridesSection": "Rate Limit Overrides", + "rateLimitOverridesMaxConcurrentHint": "Max concurrent requests override for this connection. Overrides the account-level cap.", + "rateLimitOverridesMaxConcurrentLabel": "Max Concurrent (Rate Limit)", + "rateLimitOverridesMinTimeHint": "Minimum time (ms) between requests. Overrides the default rate limiter delay.", + "rateLimitOverridesMinTimeLabel": "Min Interval (ms)", + "rateLimitOverridesRpmHint": "Max requests per minute for this connection. Overrides the provider default.", + "rateLimitOverridesRpmLabel": "RPM (Requests/min)", + "rateLimitOverridesTpdHint": "Max tokens per day for this connection. Overrides the provider default.", + "rateLimitOverridesTpdLabel": "TPD (Tokens/day)", + "rateLimitOverridesTpmHint": "Max tokens per minute for this connection. Overrides the provider default.", + "rateLimitOverridesTpmLabel": "TPM (Tokens/min)", + "searchByModel": "Search by model…", + "openWebProviderSite": "Open {host}", + "huggingchatLabel": "HuggingChat (Free)", + "huggingchatDesc": "Free LLM chat via huggingface.co/chat", + "poeWebLabel": "Poe Web", + "poeWebDesc": "Multi-model chat via poe.com", + "veniceWebLabel": "Venice Web", + "veniceWebDesc": "Privacy-focused AI chat", + "v0VercelWebLabel": "v0 Vercel Web", + "v0VercelWebDesc": "AI code generation via v0.dev", + "kimiWebLabel": "Kimi Web", + "kimiWebDesc": "Moonshot AI consumer chat via www.kimi.com (international, Connect-RPC API)", + "doubaoWebLabel": "Dola Web", + "doubaoWebDesc": "ByteDance AI chat via dola.com", + "overrideBaseUrlAdvanced": "Advanced: override base URL", + "overrideBaseUrlHint": "Advanced: point this built-in provider at a custom endpoint. Leave blank to use the default.", + "bulkAddFormatHintCloudflare": "One key per line. Format: name|accountId|apiKey (Cloudflare account ID + API token).", + "lmarenaWebCookieHint": "Open arena.ai, sign in, then copy the full Cookie header from a Network request. Include arena-auth-prod-v1.0 and arena-auth-prod-v1.1 (and further chunks if present), preferably with cf_clearance. Do not paste only the empty arena-auth-prod-v1 cookie. Optional: providerSpecificData.recaptchaV3Token if create-evaluation still returns 403." }, "settings": { "title": "Cài đặt", - "general": "chung", + "general": "Chung", "security": "Bảo mật", - "appearance": "Ngoại hình", + "appearance": "Giao diện", "routing": "Định tuyến", - "cache": "Bộ nhớ đệm", - "resilience": "khả năng phục hồi", - "routingSettingsIntro": "Kiểm soát cách định tuyến, chuyển đổi và gửi yêu cầu của bạn đến nhà cung cấp AI.", - "routingOpDropParagraphContainsLabel": "__MISSING__:Drop paragraph (contains)", - "routingOpDropParagraphStartsWithLabel": "__MISSING__:Drop paragraph (starts with)", - "routingOpReplaceTextLabel": "__MISSING__:Replace text", - "routingOpReplaceRegexLabel": "__MISSING__:Replace regex", - "routingOpDropBlockContainsLabel": "__MISSING__:Drop block (contains)", - "routingOpPrependSystemBlockLabel": "__MISSING__:Prepend system block", - "routingOpAppendSystemBlockLabel": "__MISSING__:Append system block", - "routingOpInjectBillingHeaderLabel": "__MISSING__:Inject billing header", - "routingOpObfuscateWordsLabel": "__MISSING__:Obfuscate words (ZWJ)", - "routingOpDropParagraphContainsDesc": "__MISSING__:Removes any paragraph (text block split on blank lines) inside the system prompt whose text contains ANY of the listed substrings. Use to strip third-party client fingerprints like 'github.com/anomalyco/opencode' or 'docs.openwebui.com' that Anthropic's classifier flags.", - "routingOpDropParagraphStartsWithDesc": "__MISSING__:Removes any paragraph that STARTS WITH one of the listed prefixes. Use for identity lines like 'You are OpenCode' or 'You are Open WebUI' that announce the calling client.", - "routingOpReplaceTextDesc": "__MISSING__:Replaces a literal substring with another literal substring. Use for known trigger phrases — e.g. rewrite 'Here is some useful information about the environment you are running in:' to 'Environment context you are running in:' (an empirically-validated trigger phrase).", - "routingOpReplaceRegexDesc": "__MISSING__:Replaces text matching a regular expression. Use when you need patterns (character classes, optional whitespace, anchors) instead of literal substrings. A malformed pattern is caught at runtime when the op runs.", - "routingOpDropBlockContainsDesc": "__MISSING__:Removes ENTIRE system blocks (not just paragraphs) whose text contains any of the listed substrings. Use when a whole block is fingerprint-bearing and you want it gone — e.g. an injected MCP-server description.", - "routingOpPrependSystemBlockDesc": "__MISSING__:Inserts a new text block at the FRONT of the system array. Use to add the SDK identity 'You are a Claude agent, built on Anthropic's Claude Agent SDK.' that Anthropic's classifier expects.", - "routingOpAppendSystemBlockDesc": "__MISSING__:Inserts a new text block at the END of the system array. Use for cosmetic additions that don't need to be at position [0].", - "routingOpInjectBillingHeaderDesc": "__MISSING__:Prepends the special 'x-anthropic-billing-header: cc_version=...; cc_entrypoint=...; cch=...;' text block that Anthropic's classifier validates. Required for CC bridge relay endpoints; for the native claude provider OmniRoute already injects its own billing line so this op is usually redundant there.", - "routingOpObfuscateWordsDesc": "__MISSING__:Inserts a Zero-Width-Joiner character after the first letter of each listed word, so 'opencode' becomes 'o‍pencode'. Reads identical to humans but bypasses classifier word matches. Targets system blocks, user/assistant messages, and tool descriptions.", - "routingNeedlesHint": "__MISSING__:List of substrings. A paragraph matches if it contains ANY one of them. Add one per line via 'Add entry'.", - "routingPrefixesHint": "__MISSING__:List of strings. A paragraph matches if it starts with any one of them (leading whitespace is trimmed before matching).", - "routingCaseSensitiveHint": "__MISSING__:When ON, 'OpenCode' and 'opencode' are different strings. When OFF (default), the comparison ignores case.", - "routingMatchLiteralHint": "__MISSING__:Exact literal substring to find. No regex syntax — special chars like . * ? are treated as themselves.", - "routingReplacementTextHint": "__MISSING__:Replacement string. Leave blank to delete the match. The output preserves surrounding text.", - "routingAllOccurrencesHint": "__MISSING__:When ON (default), every instance is replaced. When OFF, only the first match is replaced.", - "routingPatternHint": "__MISSING__:JavaScript regex source. Don't wrap in slashes — just 'foo(.*)bar'. Server rejects patterns that fail to compile.", - "routingRegexFlagsHint": "__MISSING__:JavaScript regex flags (g = all matches, i = case-insensitive, s = dot matches newline, m = multiline). Default 'g'.", - "routingBlockTextHint": "__MISSING__:Full text of the new system block. Use a literal string; the system block stores text only.", - "routingIdempotencyKeyHint": "__MISSING__:Optional. If set, the op skips when a block whose text starts with this key is already present. Prevents double-prepend on retries.", - "routingBillingEntrypointHint": "__MISSING__:Value injected as 'cc_entrypoint='. Anthropic accepts 'sdk-cli' (Agent SDK), 'cli' (Claude Code CLI), or other documented values.", - "routingBillingVersionFormatHint": "__MISSING__:How the 3-char build hash after cc_version= is computed. 'ex-machina' = sha256 of CCH_SALT+chars-from-first-user-msg+version (per-message). 'omniroute-daystamp' = sha256 of YYYY-MM-DD+version (stable per-day).", - "routingBillingCchAlgoHint": "__MISSING__:How the 5-char cch= token is computed. 'sha256-first-user' = sha256 of first user message text. 'xxhash64-body' = body-level signing fills it later. 'static-zero' = literal '00000' placeholder.", - "routingObfuscateWordsHint": "__MISSING__:Lowercase words to obfuscate. ZWJ insertion is applied case-insensitively, so 'opencode' also matches 'OpenCode' and 'OPENCODE'.", - "routingObfuscateTargetsHint": "__MISSING__:Which body regions to scan for the words: system blocks, user/assistant messages, and/or tool descriptions.", - "routingObfuscateTargetsLabel": "__MISSING__:Targets", - "routingSummarizeDropParagraphContains": "__MISSING__:drop paragraphs containing: {items}", - "routingSummarizeDropParagraphStartsWith": "__MISSING__:drop paragraphs starting with: {items}", - "routingSummarizeReplaceText": "__MISSING__:replace \"{match}\" → \"{replacement}\"", - "routingSummarizeReplaceRegex": "__MISSING__:regex /{pattern}/{flags} → \"{replacement}\"", - "routingSummarizeDropBlockContains": "__MISSING__:drop blocks containing: {items}", - "routingSummarizePrependSystemBlock": "__MISSING__:prepend block: \"{text}\"", - "routingSummarizeAppendSystemBlock": "__MISSING__:append block: \"{text}\"", - "routingSummarizeInjectBillingHeader": "__MISSING__:inject billing header (entrypoint={entrypoint}, version={versionFormat}, cch={cchAlgo})", - "routingSummarizeObfuscateWords": "__MISSING__:obfuscate {count} word(s) via ZWJ in {targets}", - "routingDefaultAutoVariantLKGP": "__MISSING__:Last Known Good Provider", - "routingDefaultAutoVariantLKGPDesc": "__MISSING__:Last Known Good Provider", - "routingDefaultAutoVariantCoding": "__MISSING__:Quality-first for code", - "routingDefaultAutoVariantCodingDesc": "__MISSING__:Quality-first for code", - "routingDefaultAutoVariantFast": "__MISSING__:Low-latency routing", - "routingDefaultAutoVariantFastDesc": "__MISSING__:Low-latency routing", - "routingDefaultAutoVariantCheap": "__MISSING__:Cost-optimized", - "routingDefaultAutoVariantCheapDesc": "__MISSING__:Cost-optimized", - "routingDefaultAutoVariantOffline": "__MISSING__:High availability", - "routingDefaultAutoVariantOfflineDesc": "__MISSING__:High availability", - "routingDefaultAutoVariantSmart": "__MISSING__:Best discovery (10% explore)", - "routingDefaultAutoVariantSmartDesc": "__MISSING__:Best discovery (10% explore)", - "routingOpSummaryCount": "__MISSING__:{count, plural, =0 {no ops} one {# op} other {# ops}}", - "routingOpEnabled": "__MISSING__:enabled", - "routingOpDisabled": "__MISSING__:disabled", - "routingOpStatusSeparator": "__MISSING__: ·", - "resilienceSettingsIntro": "Tự động thử lại, thời gian hồi chiêu và dự phòng khi nhà cung cấp thất bại.", - "aiSettingsIntro": "Cài đặt dành riêng cho AI để tư duy ngân sách, hành vi mô hình và nén.", - "systemPrompt": "Lời nhắc hệ thống", - "thinkingBudget": "Suy nghĩ về ngân sách", - "proxy": "ủy nhiệm", + "cache": "Cache", + "resilience": "Khả năng phục hồi", + "routingSettingsIntro": "Kiểm soát cách các yêu cầu của bạn được định tuyến, chuyển đổi và gửi đến các nhà cung cấp AI.", + "routingOpDropParagraphContainsLabel": "Loại bỏ đoạn văn (chứa)", + "routingOpDropParagraphStartsWithLabel": "Loại bỏ đoạn văn (bắt đầu bằng)", + "routingOpReplaceTextLabel": "Thay thế văn bản", + "routingOpReplaceRegexLabel": "Thay thế regex", + "routingOpDropBlockContainsLabel": "Loại bỏ khối (chứa)", + "routingOpPrependSystemBlockLabel": "Chèn khối hệ thống vào trước", + "routingOpAppendSystemBlockLabel": "Chèn khối hệ thống vào sau", + "routingOpInjectBillingHeaderLabel": "Chèn header thanh toán", + "routingOpObfuscateWordsLabel": "Xáo trộn từ ngữ (ZWJ)", + "routingOpDropParagraphContainsDesc": "Loại bỏ bất kỳ đoạn văn nào (khối văn bản được chia tách bằng các dòng trống) trong prompt hệ thống có chứa BẤT KỲ chuỗi con nào trong danh sách. Sử dụng để loại bỏ dấu vết của ứng dụng khách bên thứ ba như 'github.com/anomalyco/opencode' hoặc 'docs.openwebui.com' mà bộ phân loại của Anthropic gắn cờ.", + "routingOpDropParagraphStartsWithDesc": "Loại bỏ bất kỳ đoạn văn nào BẮT ĐẦU BẰNG một trong các tiền tố được liệt kê. Sử dụng cho các dòng định danh như 'You are OpenCode' hoặc 'You are Open WebUI' cho biết ứng dụng khách đang gọi.", + "routingOpReplaceTextDesc": "Thay thế một chuỗi con cụ thể bằng một chuỗi con cụ thể khác. Sử dụng cho các cụm từ kích hoạt đã biết — ví dụ: viết lại 'Here is some useful information about the environment you are running in:' thành 'Environment context you are running in:' (một cụm từ kích hoạt đã được xác thực bằng thực nghiệm).", + "routingOpReplaceRegexDesc": "Thay thế văn bản khớp với một biểu thức chính quy. Sử dụng khi bạn cần các mẫu (lớp ký tự, khoảng trắng tùy chọn, điểm neo) thay vì các chuỗi con cụ thể. Mẫu bị định dạng sai sẽ bị phát hiện trong thời gian chạy khi thao tác này chạy.", + "routingOpDropBlockContainsDesc": "Loại bỏ TOÀN BỘ các khối hệ thống (không chỉ các đoạn văn) có văn bản chứa bất kỳ chuỗi con nào được liệt kê. Sử dụng khi toàn bộ khối chứa dấu vết và bạn muốn loại bỏ nó — ví dụ: mô tả MCP-server được chèn vào.", + "routingOpPrependSystemBlockDesc": "Chèn một khối văn bản mới vào ĐẦU mảng hệ thống. Sử dụng để thêm định danh SDK 'You are a Claude agent, built on Anthropic's Claude Agent SDK.' mà bộ phân loại của Anthropic mong đợi.", + "routingOpAppendSystemBlockDesc": "Chèn một khối văn bản mới vào CUỐI mảng hệ thống. Sử dụng cho các bổ sung chỉ mang tính trình bày, không cần ở vị trí [0].", + "routingOpInjectBillingHeaderDesc": "Thêm vào đầu khối văn bản đặc biệt 'x-anthropic-billing-header: cc_version=...; cc_entrypoint=...; cch=...;' mà bộ phân loại của Anthropic xác thực. Bắt buộc đối với các endpoint chuyển tiếp cầu nối CC; đối với nhà cung cấp Claude gốc, OmniRoute đã tự chèn dòng thanh toán của riêng mình nên thao tác này thường dư thừa ở đó.", + "routingOpObfuscateWordsDesc": "Chèn một ký tự Zero-Width-Joiner sau chữ cái đầu tiên của mỗi từ được liệt kê, để 'opencode' trở thành 'o‍pencode'. Con người đọc vẫn thấy giống hệt nhau, nhưng cách này bỏ qua việc bộ phân loại khớp từ. Áp dụng cho các khối hệ thống, tin nhắn của người dùng/trợ lý và mô tả công cụ.", + "routingNeedlesHint": "Danh sách các chuỗi con. Một đoạn văn sẽ khớp nếu chứa BẤT KỲ chuỗi con nào trong số đó. Thêm từng mục, mỗi mục một dòng, qua 'Add entry'.", + "routingPrefixesHint": "Danh sách các chuỗi. Một đoạn văn sẽ khớp nếu nó bắt đầu bằng bất kỳ chuỗi nào trong số đó (khoảng trắng ở đầu sẽ được loại bỏ trước khi so khớp).", + "routingCaseSensitiveHint": "Khi BẬT, 'OpenCode' và 'opencode' là các chuỗi khác nhau. Khi TẮT (mặc định), việc so sánh không phân biệt chữ hoa chữ thường.", + "routingMatchLiteralHint": "Chuỗi con nguyên văn chính xác cần tìm. Không sử dụng cú pháp biểu thức chính quy — các ký tự đặc biệt như . * ? được xử lý như chính chúng.", + "routingReplacementTextHint": "Chuỗi thay thế. Để trống để xóa phần khớp. Kết quả đầu ra sẽ giữ nguyên văn bản xung quanh.", + "routingAllOccurrencesHint": "Khi BẬT (mặc định), mọi lần xuất hiện khớp đều sẽ bị thay thế. Khi TẮT, chỉ lần khớp đầu tiên được thay thế.", + "routingPatternHint": "Nguồn regex JavaScript. Không bọc trong các dấu gạch chéo — chỉ cần 'foo(.*)bar'. Máy chủ sẽ từ chối các mẫu không thể biên dịch.", + "routingRegexFlagsHint": "Các cờ regex JavaScript (g = tất cả các khớp, i = không phân biệt chữ hoa chữ thường, s = dấu chấm khớp với dòng mới, m = nhiều dòng). Mặc định là 'g'.", + "routingBlockTextHint": "Toàn bộ văn bản của khối hệ thống mới. Sử dụng chuỗi nguyên văn; khối hệ thống chỉ lưu trữ văn bản.", + "routingIdempotencyKeyHint": "Tùy chọn. Nếu được thiết lập, thao tác sẽ bỏ qua khi đã có một khối với văn bản bắt đầu bằng khóa này. Ngăn việc thêm ở đầu hai lần khi thử lại.", + "routingBillingEntrypointHint": "Giá trị được chèn dưới dạng 'cc_entrypoint='. Anthropic chấp nhận 'sdk-cli' (Agent SDK), 'cli' (Claude Code CLI), hoặc các giá trị được tài liệu hóa khác.", + "routingBillingVersionFormatHint": "Cách tính mã băm bản dựng 3 ký tự sau cc_version=. 'ex-machina' = sha256 của CCH_SALT+các ký tự từ tin nhắn đầu tiên của người dùng+phiên bản (theo từng tin nhắn). 'omniroute-daystamp' = sha256 của YYYY-MM-DD+phiên bản (ổn định theo ngày).", + "routingBillingCchAlgoHint": "Cách tính token cch= 5 ký tự. 'sha256-first-user' = sha256 của văn bản tin nhắn đầu tiên của người dùng. 'xxhash64-body' = việc ký ở cấp phần thân sẽ điền giá trị này sau. 'static-zero' = trình giữ chỗ nguyên văn '00000'.", + "routingObfuscateWordsHint": "Các từ viết thường cần che giấu. Việc chèn ZWJ được áp dụng không phân biệt chữ hoa chữ thường, vì vậy 'opencode' cũng sẽ khớp với 'OpenCode' và 'OPENCODE'.", + "routingObfuscateTargetsHint": "Những vùng nào trong phần thân cần quét các từ: các khối hệ thống, tin nhắn của người dùng/trợ lý và/hoặc mô tả công cụ.", + "routingObfuscateTargetsLabel": "Mục tiêu", + "routingSummarizeDropParagraphContains": "bỏ các đoạn văn chứa: {items}", + "routingSummarizeDropParagraphStartsWith": "bỏ các đoạn văn bắt đầu bằng: {items}", + "routingSummarizeReplaceText": "thay thế \"{match}\" → \"{replacement}\"", + "routingSummarizeReplaceRegex": "regex /{pattern}/{flags} → \"{replacement}\"", + "routingSummarizeDropBlockContains": "bỏ các khối chứa: {items}", + "routingSummarizePrependSystemBlock": "thêm khối vào trước: \"{text}\"", + "routingSummarizeAppendSystemBlock": "thêm khối vào sau: \"{text}\"", + "routingSummarizeInjectBillingHeader": "chèn header thanh toán (entrypoint={entrypoint}, version={versionFormat}, cch={cchAlgo})", + "routingSummarizeObfuscateWords": "che giấu {count} từ bằng ZWJ trong {targets}", + "routingDefaultAutoVariantLKGP": "Nhà cung cấp hoạt động tốt gần nhất đã biết", + "routingDefaultAutoVariantLKGPDesc": "Nhà cung cấp hoạt động tốt gần nhất đã biết", + "routingDefaultAutoVariantCoding": "Ưu tiên chất lượng cho mã nguồn", + "routingDefaultAutoVariantCodingDesc": "Ưu tiên chất lượng cho mã nguồn", + "routingDefaultAutoVariantFast": "Định tuyến độ trễ thấp", + "routingDefaultAutoVariantFastDesc": "Định tuyến độ trễ thấp", + "routingDefaultAutoVariantCheap": "Tối ưu hóa chi phí", + "routingDefaultAutoVariantCheapDesc": "Tối ưu hóa chi phí", + "routingDefaultAutoVariantOffline": "Độ khả dụng cao", + "routingDefaultAutoVariantOfflineDesc": "Độ khả dụng cao", + "routingDefaultAutoVariantSmart": "Khám phá tối ưu (thử nghiệm 10%)", + "routingDefaultAutoVariantSmartDesc": "Khám phá tối ưu (thử nghiệm 10%)", + "routingOpSummaryCount": "{count, plural, =0 {không có thao tác nào} one {# thao tác} other {# thao tác}}", + "routingOpEnabled": "đã bật", + "routingOpDisabled": "đã tắt", + "routingOpStatusSeparator": "·", + "resilienceSettingsIntro": "Tự động thử lại, thời gian chờ và dự phòng khi nhà cung cấp gặp sự cố.", + "aiSettingsIntro": "Cài đặt dành riêng cho AI về ngân sách tư duy, hành vi mô hình và nén dữ liệu.", + "systemPrompt": "Prompt hệ thống", + "thinkingBudget": "Ngân sách tư duy", + "proxy": "Proxy", "httpProxy": "HTTP Proxy", "1proxy": "1proxy", - "proxySubTabsAria": "Proxy sections", - "requestBodyLimitTitle": "Request Body Limit", - "requestBodyLimitDescription": "Maximum API payload size accepted before a request body is parsed. Dedicated upload routes keep at least their built-in 100 MB limit.", - "requestBodyLimitInputLabel": "Request body limit in MB", - "requestBodyLimitEmptyError": "Enter a limit in MB", - "requestBodyLimitWholeNumberError": "Use a whole number", - "requestBodyLimitMinimumError": "Minimum is {min} MB", - "requestBodyLimitMaximumError": "Maximum is {max} MB", - "requestBodyLimitLoadFailed": "Failed to load request limit settings", - "requestBodyLimitSaveSuccess": "Request body limit saved", - "requestBodyLimitSaveFailed": "Failed to save request body limit", - "requestBodyLimitSaving": "Saving...", - "requestBodyLimitSave": "Save", - "requestBodyLimitCurrent": "Current: {value}", - "mitmProxy": "Ủy quyền MITM", + "proxySubTabsAria": "Các phần proxy", + "requestBodyLimitTitle": "Giới hạn phần thân yêu cầu", + "requestBodyLimitDescription": "Kích thước payload API tối đa được chấp nhận trước khi phần thân yêu cầu được phân tích cú pháp. Các tuyến tải lên chuyên dụng vẫn duy trì giới hạn tích hợp ít nhất 100 MB.", + "requestBodyLimitInputLabel": "Giới hạn phần thân yêu cầu tính bằng MB", + "requestBodyLimitEmptyError": "Nhập giới hạn tính bằng MB", + "requestBodyLimitWholeNumberError": "Sử dụng một số nguyên", + "requestBodyLimitMinimumError": "Tối thiểu là {min} MB", + "requestBodyLimitMaximumError": "Tối đa là {max} MB", + "requestBodyLimitLoadFailed": "Không thể tải cài đặt giới hạn phần thân yêu cầu", + "requestBodyLimitSaveSuccess": "Đã lưu giới hạn phần thân yêu cầu", + "requestBodyLimitSaveFailed": "Không thể lưu giới hạn phần thân yêu cầu", + "requestBodyLimitSaving": "Đang lưu...", + "requestBodyLimitSave": "Lưu", + "requestBodyLimitCurrent": "Hiện tại: {value}", + "mitmProxy": "MITM Proxy", "pricing": "Định giá", "storage": "Lưu trữ", "policies": "Chính sách", "ipFilter": "Bộ lọc IP", "comboDefaults": "Mặc định kết hợp", "fallbackChains": "Chuỗi dự phòng", - "changePassword": "Thay đổi mật khẩu", - "enablePassword": "Kích hoạt mật khẩu", + "changePassword": "Đổi mật khẩu", + "enablePassword": "Bật mật khẩu", "darkMode": "Chế độ tối", - "lightMode": "Chế độ ánh sáng", - "memoryTitle": "Memory", - "memoryDesc": "Persistent cross-session conversational memory", - "memoryEnabled": "Enable Memory", - "memoryEnabledDesc": "When enabled, OmniRoute will inject relevant past context.", - "maxTokens": "Max Tokens", - "retentionDays": "Retention", - "recent": "Recent", - "recentDesc": "Chronological window", - "semantic": "Semantic", - "semanticDesc": "Vector search", - "hybrid": "Hybrid", - "hybridDesc": "Recent + Semantic", - "skillsTitle": "Skills", - "skillsDesc": "Tools for models", - "skillsEnabled": "Enable Skills", - "skillsEnabledDesc": "Allows agents to trigger functions.", - "skillsComingSoon": "Skills marketplace coming soon.", - "memorySkillsTitle": "Memory & Skills", - "memorySkillsDesc": "Persistent context & capabilities", - "modelsDevTitle": "Model Database", - "modelsDevDesc": "Auto-sync pricing, capabilities & specs from models.dev", - "modelsDevEnabled": "Enable models.dev Sync", - "modelsDevEnabledDesc": "Fetch model pricing, capabilities, and specs from the open-source models.dev database", - "modelsDevInterval": "Sync Interval", - "syncNow": "Sync Now", - "syncing": "Syncing...", - "lastSync": "Last sync", - "never": "Never", - "justNow": "ngay bây giờ", - "modelsDevStats": "Sync Statistics", - "modelsDevStatsDesc": "Current models.dev data coverage", + "lightMode": "Chế độ sáng", + "memoryTitle": "Bộ nhớ", + "memoryDesc": "Bộ nhớ hội thoại liên tục qua các phiên", + "memoryEnabled": "Bật bộ nhớ", + "memoryEnabledDesc": "Khi được bật, OmniRoute sẽ chèn ngữ cảnh trước đây có liên quan.", + "maxTokens": "Token tối đa", + "retentionDays": "Thời gian lưu trữ", + "recent": "Gần đây", + "recentDesc": "Cửa sổ theo thời gian", + "semantic": "Ngữ nghĩa", + "semanticDesc": "Tìm kiếm vector", + "hybrid": "Kết hợp", + "hybridDesc": "Gần đây + Ngữ nghĩa", + "skillsTitle": "Kỹ năng", + "skillsDesc": "Công cụ dành cho mô hình", + "skillsEnabled": "Bật kỹ năng", + "skillsEnabledDesc": "Cho phép các tác nhân gọi hàm.", + "skillsComingSoon": "Chợ kỹ năng sắp ra mắt.", + "memorySkillsTitle": "Bộ nhớ & Kỹ năng", + "memorySkillsDesc": "Ngữ cảnh và năng lực lâu dài", + "modelsDevTitle": "Cơ sở dữ liệu Mô hình", + "modelsDevDesc": "Tự động đồng bộ hóa giá cả, năng lực & thông số kỹ thuật từ models.dev", + "modelsDevEnabled": "Bật đồng bộ hóa models.dev", + "modelsDevEnabledDesc": "Lấy giá cả, năng lực và thông số kỹ thuật của mô hình từ cơ sở dữ liệu mã nguồn mở models.dev", + "modelsDevInterval": "Khoảng thời gian đồng bộ", + "syncNow": "Đồng bộ ngay", + "syncing": "Đang đồng bộ...", + "lastSync": "Lần đồng bộ cuối", + "never": "Chưa bao giờ", + "justNow": "Vừa xong", + "modelsDevStats": "Thống kê đồng bộ", + "modelsDevStatsDesc": "Mức độ bao phủ dữ liệu models.dev hiện tại", "providers": "Nhà cung cấp", - "modelsWithPricing": "Models with Pricing", - "capabilities": "Capabilities", - "lastSyncCount": "Last Sync Count", - "lastSyncFull": "Last full sync", - "modelsDevInfo": "How It Works", - "modelsDevInfoDesc": "models.dev is an open-source database of AI model specifications maintained by the SST/OpenCode team. It provides pricing, capabilities, context limits, and modalities for 4,000+ models across 100+ providers.", - "modelsDevInfoResolution": "Pricing resolution order (highest priority first):", - "modelsDevInfoOrder": "User Override → models.dev → LiteLLM → Hardcoded Default", + "modelsWithPricing": "Mô hình có giá", + "capabilities": "Khả năng", + "lastSyncCount": "Số lượng đồng bộ lần cuối", + "lastSyncFull": "Lần đồng bộ đầy đủ cuối", + "modelsDevInfo": "Cách thức hoạt động", + "modelsDevInfoDesc": "models.dev là cơ sở dữ liệu mã nguồn mở về thông số kỹ thuật của các mô hình AI, do đội ngũ SST/OpenCode duy trì. Nền tảng này cung cấp thông tin về giá, khả năng, giới hạn ngữ cảnh và phương thức cho hơn 4.000 mô hình thuộc hơn 100 nhà cung cấp.", + "modelsDevInfoResolution": "Thứ tự áp dụng giá (ưu tiên từ cao đến thấp):", + "modelsDevInfoOrder": "Ghi đè của người dùng → models.dev → LiteLLM → Mặc định mã hóa cứng", "systemTheme": "Chủ đề hệ thống", - "debugToggle": "Enable Debug Mode", - "sidebarVisibilityToggle": "Show Sidebar Items", - "enableCache": "Bật bộ đệm", - "cacheTTL": "Bộ nhớ đệm TTL", - "maxCacheSize": "Kích thước bộ đệm tối đa", - "clearCache": "Xóa bộ nhớ đệm", - "cacheCleared": "Cache cleared successfully", - "clearCacheFailed": "Failed to clear cache", - "cacheHits": "Số lần truy cập bộ đệm", - "cacheMisses": "Thiếu bộ nhớ đệm", + "debugToggle": "Bật chế độ gỡ lỗi", + "sidebarVisibilityToggle": "Hiển thị các mục trên thanh bên", + "enableCache": "Bật cache", + "cacheTTL": "Cache TTL", + "maxCacheSize": "Kích thước cache tối đa", + "clearCache": "Xóa cache", + "cacheCleared": "Đã xóa cache thành công", + "clearCacheFailed": "Không thể xóa cache", + "cacheHits": "Lượt trúng cache", + "cacheMisses": "Lượt không trúng cache", "hitRate": "Tỷ lệ trúng", - "cacheEntries": "Mục nhập bộ nhớ đệm", - "cacheSettings": "Cache Settings", - "semanticCache": "Semantic Cache", - "maxEntries": "Max Entries", - "ttlMinutes": "TTL (minutes)", - "promptCache": "Bộ nhớ đệm nhắc nhở", - "strategy": "Strategy", - "preserveClientCache": "Preserve Client Cache", - "enabled": "Enabled", - "loading": "Loading...", + "cacheEntries": "Các mục cache", + "cacheSettings": "Cài đặt cache", + "semanticCache": "Cache ngữ nghĩa", + "maxEntries": "Số lượng mục tối đa", + "ttlMinutes": "TTL (phút)", + "promptCache": "Cache prompt", + "strategy": "Chiến lược", + "preserveClientCache": "Giữ lại cache phía máy khách", + "enabled": "Đã kích hoạt", + "loading": "Đang tải…", "saving": "Đang lưu...", - "save": "Save", + "save": "Lưu", "circuitBreaker": "Bộ ngắt mạch", "retryPolicy": "Chính sách thử lại", "maxRetries": "Số lần thử lại tối đa", - "retryDelay": "Trì hoãn thử lại", + "retryDelay": "Thời gian trễ thử lại", "timeoutMs": "Thời gian chờ (ms)", - "enableSystemPrompt": "Kích hoạt lời nhắc hệ thống", - "systemPromptText": "Văn bản nhắc nhở hệ thống", - "autoDisableBannedAccounts": "Auto-Disable Banned Accounts", - "autoDisableDescription": "Permanently mark provider connections as deactivated if they return specific terminal ban signals (e.g. HTTP 403 'verify your account'). This removes them from the combo rotation.", - "autoDisableThreshold": "Ban Threshold", - "autoDisableThresholdDesc": "Consecutive ban signals required before permanent deactivation.", - "resilienceStructureTitle": "Resilience Structure", - "resilienceStructureDesc": "Trang này chỉ cấu hình hành vi. Trạng thái ngắt trực tiếp được hiển thị trên trang Sức khỏe. Thử lại theo từng combo cụ thể và kiểm soát vị trí quay vòng vẫn nằm trong cài đặt kết hợp.", + "enableSystemPrompt": "Bật prompt hệ thống", + "systemPromptText": "Văn bản prompt hệ thống", + "autoDisableBannedAccounts": "Tự động vô hiệu hóa tài khoản bị cấm", + "autoDisableDescription": "Đánh dấu vĩnh viễn các kết nối nhà cung cấp là đã vô hiệu hóa nếu chúng trả về các tín hiệu cấm không thể khắc phục cụ thể (ví dụ: HTTP 403 'verify your account'). Điều này sẽ loại bỏ chúng khỏi vòng xoay combo.", + "autoDisableThreshold": "Ngưỡng cấm", + "autoDisableThresholdDesc": "Số lượng tín hiệu cấm liên tiếp cần thiết trước khi hủy kích hoạt vĩnh viễn.", + "resilienceStructureTitle": "Cấu trúc chịu lỗi", + "resilienceStructureDesc": "Trang này chỉ cấu hình hành vi. Trạng thái bộ ngắt mạch theo thời gian thực được hiển thị trên trang Sức khỏe. Các cài đặt thử lại và kiểm soát khe round-robin riêng cho từng tổ hợp vẫn nằm trong cài đặt tổ hợp.", "enableThinking": "Kích hoạt tư duy", - "maxThinkingTokens": "Mã thông báo tư duy tối đa", + "maxThinkingTokens": "Số token tư duy tối đa", "enableProxy": "Kích hoạt proxy", - "proxyUrl": "URL proxy", - "pricingRates": "Định dạng giá cước", + "proxyUrl": "Proxy URL", + "pricingRates": "Định dạng mức giá", "currentPricing": "Tổng quan về giá hiện tại", "loadingPricing": "Đang tải dữ liệu giá...", "noPricing": "Không có dữ liệu giá cả", - "input": "đầu vào", - "output": "đầu ra", - "cached": "Đã lưu vào bộ nhớ đệm", - "reasoning": "Lý luận", - "cacheCreation": "Tạo bộ đệm", + "input": "Đầu vào", + "output": "Đầu ra", + "cached": "Đã lưu trong cache", + "reasoning": "Lập luận", + "cacheCreation": "Tạo cache", "customPricing": "Giá tùy chỉnh", "databaseSize": "Kích thước cơ sở dữ liệu", "backupDb": "Sao lưu cơ sở dữ liệu", @@ -4649,37 +5178,37 @@ "exportData": "Xuất dữ liệu", "importData": "Nhập dữ liệu", "clearData": "Xóa tất cả dữ liệu", - "clearDataConfirm": "Điều này sẽ xóa vĩnh viễn tất cả dữ liệu. Bạn có chắc không?", - "enableRequestLogs": "Bật nhật ký yêu cầu", - "logRetention": "Lưu giữ nhật ký", - "ipWhitelist": "Danh sách trắng IP", - "ipBlacklist": "Danh sách đen IP", + "clearDataConfirm": "Hành động này sẽ xóa vĩnh viễn tất cả dữ liệu. Bạn có chắc chắn không?", + "enableRequestLogs": "Kích hoạt nhật ký yêu cầu", + "logRetention": "Thời gian lưu trữ nhật ký", + "ipWhitelist": "Danh sách IP được cho phép", + "ipBlacklist": "Danh sách IP bị chặn", "addIP": "Thêm IP", - "savedSuccessfully": "Đã lưu cài đặt thành công", - "ai": "trí tuệ nhân tạo", + "savedSuccessfully": "Cài đặt đã được lưu thành công", + "ai": "AI", "advanced": "Nâng cao", - "localMode": "Chế độ cục bộ - Tất cả dữ liệu được lưu trữ trên máy của bạn", - "settingsSectionsAria": "Phần cài đặt", + "localMode": "Chế độ cục bộ — Tất cả dữ liệu được lưu trữ trên máy của bạn", + "settingsSectionsAria": "Các phần cài đặt", "switchThemes": "Chuyển đổi giữa chủ đề sáng và tối", "themeSelectionAria": "Lựa chọn chủ đề", - "themeLight": "Ánh sáng", + "themeLight": "Sáng", "themeDark": "Tối", "themeSystem": "Hệ thống", - "endpointTunnelVisibility": "Khả năng hiển thị đường hầm điểm cuối", - "endpointTunnelVisibilityDesc": "Ẩn các điều khiển đường hầm khỏi trang Điểm cuối mà không thay đổi trạng thái đường hầm.", - "showCloudflareTunnel": "Đường hầm nhanh Cloudflare", - "showCloudflareTunnelDesc": "Hiển thị các điều khiển Đường hầm nhanh của Cloudflare trên trang Điểm cuối.", - "showTailscaleFunnel": "Phễu đuôi", - "showTailscaleFunnelDesc": "Hiển thị các điều khiển Kênh Tailscale trên trang Điểm cuối.", - "showNgrokTunnel": "đường hầm ngrok", - "showNgrokTunnelDesc": "Hiển thị các điều khiển Đường hầm ngrok trên trang Điểm cuối.", - "sidebarVisibility": "Hide sidebar items", - "sidebarVisibilityDesc": "Hide any sidebar navigation entry to reduce visual clutter.", - "sidebarVisibilityHint": "Any sidebar section is hidden automatically when a...", + "endpointTunnelVisibility": "Hiển thị đường hầm endpoint", + "endpointTunnelVisibilityDesc": "Ẩn các nút điều khiển đường hầm khỏi trang Endpoint mà không làm thay đổi trạng thái đường hầm.", + "showCloudflareTunnel": "Cloudflare Quick Tunnel", + "showCloudflareTunnelDesc": "Hiển thị các nút điều khiển Cloudflare Quick Tunnel trên trang Endpoint.", + "showTailscaleFunnel": "Tailscale Funnel", + "showTailscaleFunnelDesc": "Hiển thị các nút điều khiển Tailscale Funnel trên trang Endpoint.", + "showNgrokTunnel": "ngrok Tunnel", + "showNgrokTunnelDesc": "Hiển thị các nút điều khiển ngrok Tunnel trên trang Endpoint.", + "sidebarVisibility": "Ẩn các mục trên thanh bên", + "sidebarVisibilityDesc": "Ẩn bất kỳ mục điều hướng nào trên thanh bên để giảm bớt sự lộn xộn về mặt trực quan mà không vô hiệu hóa bất kỳ tính năng nào", + "sidebarVisibilityHint": "Bất kỳ phần nào trên thanh bên sẽ tự động bị ẩn khi tất cả các mục bên trong nó đều bị ẩn", "hideHealthLogs": "Ẩn nhật ký kiểm tra sức khỏe", - "hideHealthLogsDesc": "Khi BẬT, hãy chặn thông báo [HealthCheck] trong bảng điều khiển máy chủ", + "hideHealthLogsDesc": "Khi BẬT, sẽ chặn các thông báo [HealthCheck] trong bảng điều khiển máy chủ", "themeAccent": "Màu chủ đề", - "themeAccentDesc": "Chọn màu đặt sẵn hoặc tạo chủ đề của riêng bạn bằng một màu", + "themeAccentDesc": "Chọn màu thiết lập sẵn hoặc tạo chủ đề của riêng bạn bằng một màu", "themeCreate": "Tạo chủ đề", "themeCustom": "Chủ đề tùy chỉnh", "themeBlue": "Xanh dương", @@ -4688,72 +5217,72 @@ "themeViolet": "Tím", "themeOrange": "Cam", "themeCyan": "Lục lam", - "whitelabeling": "Branding", - "whitelabelingDesc": "Customize the application name and logo", - "appName": "Application Name", - "appNameDesc": "Display name shown in sidebar and browser tab", - "customLogo": "Custom Logo URL", - "customLogoDesc": "URL to your custom logo image", - "uploadLogo": "Upload Logo", - "resetLogo": "Reset to Default", - "logoPreview": "Preview", - "customFavicon": "Browser Favicon", - "customFaviconDesc": "URL to your custom favicon (shown in browser tab)", - "uploadFavicon": "Upload Favicon", - "resetFavicon": "Reset Favicon", - "faviconPreview": "Favicon Preview", - "flushCache": "Xóa bộ nhớ đệm", - "flushing": "Đang xả…", + "whitelabeling": "Nhận diện thương hiệu", + "whitelabelingDesc": "Tùy chỉnh tên ứng dụng và logo", + "appName": "Tên ứng dụng", + "appNameDesc": "Tên hiển thị trên thanh bên và tab trình duyệt", + "customLogo": "URL logo tùy chỉnh", + "customLogoDesc": "URL dẫn đến hình ảnh logo tùy chỉnh của bạn", + "uploadLogo": "Tải lên logo", + "resetLogo": "Đặt lại về mặc định", + "logoPreview": "Xem trước", + "customFavicon": "Favicon trình duyệt", + "customFaviconDesc": "URL dẫn đến favicon tùy chỉnh của bạn (hiển thị trên tab trình duyệt)", + "uploadFavicon": "Tải lên favicon", + "resetFavicon": "Đặt lại favicon", + "faviconPreview": "Xem trước favicon", + "flushCache": "Xóa cache", + "flushing": "Đang xóa cache…", "size": "Kích thước", "hits": "Lượt truy cập", - "evictions": "Trục xuất", - "loadingCacheStats": "Đang tải số liệu thống kê về bộ nhớ đệm…", + "evictions": "Lượt loại bỏ", + "loadingCacheStats": "Đang tải thống kê cache…", "globalProxy": "Proxy toàn cầu", - "globalProxyDesc": "Định cấu hình proxy gửi đi toàn cầu cho tất cả lệnh gọi API. Các nhà cung cấp, tổ hợp và khóa riêng lẻ có thể ghi đè điều này.", - "noGlobalProxy": "Không có proxy toàn cầu nào được định cấu hình", - "bulkHealthcheck": "Bulk Healthcheck", - "bulkHealthcheckDesc": "Test all configured proxies against a target URL to find which ones work.", - "healthcheckTesting": "Testing...", - "healthcheckAll": "Healthcheck All", - "healthcheckFailed": "Failed to run healthcheck", - "healthcheckTestingAll": "Testing all proxies in parallel...", - "healthcheckTotal": "Total", - "healthcheckWorking": "Working", - "healthcheckFailedLabel": "Failed", - "healthcheckStatus": "Status", - "healthcheckProxyUrl": "Proxy URL", - "healthcheckLatency": "Latency", - "globalLabel": "Toàn cầu", + "globalProxyDesc": "Định cấu hình proxy gửi đi toàn cầu cho tất cả các lệnh gọi API. Các nhà cung cấp, tổ hợp và khóa riêng lẻ có thể ghi đè cài đặt này.", + "noGlobalProxy": "Chưa định cấu hình proxy toàn cầu", + "bulkHealthcheck": "Kiểm tra tình trạng hàng loạt", + "bulkHealthcheckDesc": "Kiểm tra tất cả proxy đã cấu hình với một URL đích để xác định proxy nào hoạt động.", + "healthcheckTesting": "Đang kiểm tra...", + "healthcheckAll": "Kiểm tra tình trạng tất cả proxy", + "healthcheckFailed": "Không thể chạy kiểm tra tình trạng", + "healthcheckTestingAll": "Đang kiểm tra song song tất cả các proxy...", + "healthcheckTotal": "Tổng số", + "healthcheckWorking": "Đang hoạt động", + "healthcheckFailedLabel": "Thất bại", + "healthcheckStatus": "Trạng thái", + "healthcheckProxyUrl": "URL proxy", + "healthcheckLatency": "Độ trễ", + "globalLabel": "Toàn cục", "configure": "Cấu hình", - "globalSystemPrompt": "Lời nhắc hệ thống toàn cầu", + "globalSystemPrompt": "Prompt hệ thống toàn cục", "saved": "Đã lưu", - "beforePromptLabel": "__MISSING__:Before Prompt", - "beforePromptDesc": "__MISSING__:Injected before agent/provider system instructions", - "beforePromptPlaceholder": "__MISSING__:Instructions inserted before agent/provider prompt...", - "afterPromptLabel": "__MISSING__:After Prompt", - "afterPromptDesc": "__MISSING__:Injected after agent/provider system instructions", - "afterPromptPlaceholder": "__MISSING__:Instructions inserted after agent/provider prompt...", + "beforePromptLabel": "Trước prompt", + "beforePromptDesc": "Được chèn vào trước hướng dẫn hệ thống của agent/nhà cung cấp", + "beforePromptPlaceholder": "Các hướng dẫn được chèn trước prompt của agent/nhà cung cấp...", + "afterPromptLabel": "Sau prompt", + "afterPromptDesc": "Được chèn vào sau hướng dẫn hệ thống của agent/nhà cung cấp", + "afterPromptPlaceholder": "Các hướng dẫn được chèn sau prompt của agent/nhà cung cấp...", "chars": "{count} ký tự", - "thinkingBudgetTitle": "Suy nghĩ về ngân sách", - "thinkingBudgetDesc": "Kiểm soát việc sử dụng mã thông báo lý luận AI trên tất cả các yêu cầu", - "passthrough": "Truyền qua", - "passthroughDesc": "Không có thay đổi - khách hàng kiểm soát ngân sách tư duy", - "auto": "Tự động", - "autoDesc": "Loại bỏ mọi cấu hình suy nghĩ - hãy để nhà cung cấp quyết định", - "custom": "tùy chỉnh", - "customDesc": "Đặt ngân sách mã thông báo cố định cho tất cả các yêu cầu", + "thinkingBudgetTitle": "Ngân sách suy nghĩ", + "thinkingBudgetDesc": "Kiểm soát việc sử dụng token suy luận của AI trên tất cả các yêu cầu", + "passthrough": "Chuyển tiếp nguyên trạng", + "passthroughDesc": "Không thay đổi — máy khách tự kiểm soát ngân sách suy nghĩ", + "auto": "Kết hợp tự động", + "autoDesc": "Nhóm định tuyến thông minh tự khắc phục lỗi (tối ưu hóa hiệu suất)", + "custom": "Tùy chỉnh", + "customDesc": "Đặt ngân sách token cố định cho tất cả các yêu cầu", "adaptive": "Thích ứng", - "adaptiveDesc": "Mở rộng ngân sách dựa trên độ phức tạp của yêu cầu", - "effortNone": "Không có (0 mã thông báo)", + "adaptiveDesc": "Điều chỉnh ngân sách dựa trên độ phức tạp của yêu cầu", + "effortNone": "Không có (0 token)", "effortLow": "Thấp (1K token)", "effortMedium": "Trung bình (10K token)", "effortHigh": "Cao (128K token)", - "tokenBudget": "Ngân sách mã thông báo", - "tokens": "mã thông báo", + "tokenBudget": "Ngân sách token", + "tokens": "token", "baseEffortLevel": "Mức nỗ lực cơ bản", - "adaptiveHint": "Chế độ thích ứng sẽ chia tỷ lệ từ cấp cơ sở này dựa trên số lượng tin nhắn, mức sử dụng công cụ và độ dài lời nhắc.", + "adaptiveHint": "Chế độ thích ứng sẽ điều chỉnh quy mô từ mức cơ bản này dựa trên số lượng tin nhắn, mức sử dụng công cụ và độ dài prompt.", "requireLogin": "Yêu cầu đăng nhập", - "requireLoginDesc": "Khi BẬT, bảng điều khiển yêu cầu mật khẩu. Khi TẮT, truy cập mà không cần đăng nhập.", + "requireLoginDesc": "Khi BẬT, bảng điều khiển yêu cầu mật khẩu. Khi TẮT, có thể truy cập mà không cần đăng nhập.", "currentPassword": "Mật khẩu hiện tại", "enterCurrentPassword": "Nhập mật khẩu hiện tại", "newPassword": "Mật khẩu mới", @@ -4761,222 +5290,222 @@ "confirmPassword": "Xác nhận mật khẩu mới", "confirmPasswordPlaceholder": "Xác nhận mật khẩu mới", "passwordsNoMatch": "Mật khẩu không khớp", - "passwordUpdated": "Đã cập nhật mật khẩu thành công", - "failedUpdatePassword": "Không cập nhật được mật khẩu", + "passwordUpdated": "Cập nhật mật khẩu thành công", + "failedUpdatePassword": "Không thể cập nhật mật khẩu", "errorOccurred": "Đã xảy ra lỗi", "updatePassword": "Cập nhật mật khẩu", "setPassword": "Đặt mật khẩu", - "apiEndpointProtection": "Bảo vệ điểm cuối API", - "requireAuthModels": "Yêu cầu khóa API cho /model", - "requireAuthModelsDesc": "Khi BẬT, điểm cuối /v1/models trả về 404 cho các yêu cầu không được xác thực. Ngăn chặn việc phát hiện mô hình bởi người dùng trái phép.", - "authModelHeading": "Mô hình ủy quyền hoạt động", - "authModelClient": "Điểm cuối API máy khách (/v1/*, /chat/*, /responses/*, /codex/*, /messages/*) yêu cầu khóa API Bearer.", - "authModelManagement": "Điểm cuối quản lý (/bảng thông tin, /api/*) yêu cầu phiên bảng thông tin hoặc thông tin xác thực quản lý.", - "authModelPublic": "Chỉ các tuyến đăng nhập, sức khỏe và bootstrap là công khai.", - "bruteForceProtection": "Đăng nhập bảo vệ bạo lực", - "bruteForceProtectionDesc": "Điều tiết và khóa /api/auth/login sau nhiều lần thất bại từ cùng một IP.", - "corsAllowedOrigins": "Nguồn gốc được phép CORS", - "corsAllowedOriginsDesc": "Danh sách nguồn gốc trình duyệt được phân tách bằng dấu phẩy được phép gọi máy chủ này. Danh sách trống = không có quyền truy cập CORS của trình duyệt (từ máy chủ đến máy chủ vẫn hoạt động). Chỉ sử dụng CORS_ALLOW_ALL=true env var để phát triển.", + "apiEndpointProtection": "Bảo vệ endpoint API", + "requireAuthModels": "Yêu cầu khóa API cho /models", + "requireAuthModelsDesc": "Khi BẬT, endpoint /v1/models sẽ trả về 404 cho các yêu cầu không được xác thực. Ngăn chặn việc phát hiện mô hình bởi người dùng không có quyền.", + "authModelHeading": "Mô hình phân quyền đang hoạt động", + "authModelClient": "Các điểm cuối API phía máy khách (/v1/*, /chat/*, /responses/*, /codex/*, /messages/*) yêu cầu khóa API dạng Bearer.", + "authModelManagement": "Các điểm cuối quản lý (/dashboard, /api/*) yêu cầu phiên Bảng điều khiển hoặc thông tin xác thực quản lý.", + "authModelPublic": "Chỉ các đường dẫn đăng nhập, kiểm tra tình trạng và khởi tạo là công khai.", + "bruteForceProtection": "Bảo vệ chống tấn công vét cạn khi đăng nhập", + "bruteForceProtectionDesc": "Giới hạn tần suất và khóa /api/auth/login sau nhiều lần thất bại liên tiếp từ cùng một IP.", + "corsAllowedOrigins": "Nguồn gốc được CORS cho phép", + "corsAllowedOriginsDesc": "Danh sách nguồn gốc của trình duyệt được phép gọi máy chủ này, phân tách bằng dấu phẩy. Danh sách trống = không cho phép truy cập CORS từ trình duyệt (kết nối giữa các máy chủ vẫn hoạt động). Chỉ sử dụng biến môi trường CORS_ALLOW_ALL=true cho môi trường phát triển.", "blockedProviders": "Nhà cung cấp bị chặn", "blockedProvidersDesc": "Ẩn các nhà cung cấp cụ thể khỏi phản hồi /v1/models. Các nhà cung cấp bị chặn sẽ không xuất hiện trong danh sách mô hình.", - "providersBlocked": "{count} nhà cung cấp bị chặn khỏi /models", + "providersBlocked": "Đã chặn {count} nhà cung cấp khỏi /models", "blockProviderTitle": "Chặn {provider}", "unblockProviderTitle": "Bỏ chặn {provider}", - "cliFingerprint": "CLI Fingerprint Matching", - "cliFingerprintDesc": "Match native CLI binary signatures when proxying requests. Reorders headers and body fields to look identical to the official CLI tools. Your proxy IP is preserved.", - "cliFingerprintEnabled": "{count} provider(s) with CLI fingerprint active", - "enableFingerprintTitle": "Enable fingerprint for {provider}", - "disableFingerprintTitle": "Disable fingerprint for {provider}", - "systemTransforms": "Đường ống chuyển đổi khối hệ thống", - "systemTransformsDesc": "Quy trình chuyển đổi theo yêu cầu của mỗi nhà cung cấp được áp dụng cho nội dung yêu cầu trước khi chuyển tiếp. Hỗ trợ bất kỳ ID nhà cung cấp nào.", + "cliFingerprint": "Đối sánh dấu vân tay CLI", + "cliFingerprintDesc": "Chuẩn hóa các header của yêu cầu và trường trong phần thân để khớp với chữ ký của công cụ CLI chính thức. Kích hoạt riêng cho từng nhà cung cấp.", + "cliFingerprintEnabled": "Có {count} nhà cung cấp đang bật dấu vân tay CLI", + "enableFingerprintTitle": "Bật dấu vân tay cho {provider}", + "disableFingerprintTitle": "Tắt dấu vân tay cho {provider}", + "systemTransforms": "Quy trình chuyển đổi khối hệ thống", + "systemTransformsDesc": "Quy trình chuyển đổi có thứ tự theo từng nhà cung cấp, được áp dụng cho phần thân yêu cầu trước khi chuyển tiếp. Hỗ trợ mọi ID nhà cung cấp.", "systemTransformsAddProvider": "Thêm nhà cung cấp", - "systemTransformsAddProviderPlaceholder": "Chọn nhà cung cấp…", - "systemTransformsAddProviderAllConfigured": "Tất cả các nhà cung cấp đã được định cấu hình", + "systemTransformsAddProviderPlaceholder": "Chọn một nhà cung cấp…", + "systemTransformsAddProviderAllConfigured": "Tất cả nhà cung cấp đã được cấu hình", "systemTransformsRemoveProvider": "Xóa nhà cung cấp", - "systemTransformsNoProviders": "Không có nhà cung cấp nào được định cấu hình. Thêm nhà cung cấp để bắt đầu.", + "systemTransformsNoProviders": "Chưa có nhà cung cấp nào được cấu hình. Thêm một nhà cung cấp để bắt đầu.", "systemTransformsOpMoveUp": "Di chuyển lên", "systemTransformsOpMoveDown": "Di chuyển xuống", - "systemTransformsOpDelete": "Xóa lệnh", + "systemTransformsOpDelete": "Xóa thao tác", "routingStrategy": "Chiến lược định tuyến", "routingAdvancedGuideTitle": "Hướng dẫn định tuyến nâng cao", - "routingAdvancedGuideHint1": "Sử dụng Fill First để có mức độ ưu tiên có thể dự đoán được, Round Robin để đảm bảo tính công bằng và P2C để có khả năng phục hồi độ trễ.", - "routingAdvancedGuideHint2": "Nếu các nhà cung cấp khác nhau về chất lượng/chi phí, hãy bắt đầu với Cost Opt cho công việc nền và Ít được sử dụng nhất để cân bằng độ hao mòn.", - "fillFirst": "điền đầu tiên", - "fillFirstDesc": "Sử dụng tài khoản theo thứ tự ưu tiên", - "roundRobin": "Vòng Robin", - "roundRobinDesc": "Duyệt qua tất cả các tài khoản", + "routingAdvancedGuideHint1": "Chiến lược này được đồng bộ hóa với cả giá trị mặc định của combo mới và định tuyến dự phòng tài khoản toàn cục.", + "routingAdvancedGuideHint2": "Sử dụng Fill First để có thứ tự ưu tiên tài khoản dễ dự đoán, kết hợp Round Robin với Sticky Limit cho các lô tài khoản và dùng P2C để chống chịu tốt hơn trước độ trễ.", + "fillFirst": "Fill First", + "fillFirstDesc": "Sử dụng các tài khoản theo thứ tự ưu tiên", + "roundRobin": "Round Robin", + "roundRobinDesc": "Xoay vòng qua tất cả các tài khoản", "p2c": "P2C", - "p2cDesc": "Chọn ngẫu nhiên 2 cái, chọn cái lành mạnh hơn", + "p2cDesc": "Chọn ngẫu nhiên 2 tài khoản, chọn tài khoản hoạt động tốt hơn", "random": "Ngẫu nhiên", - "randomDesc": "Tài khoản ngẫu nhiên mỗi yêu cầu", - "leastUsed": "Ít được sử dụng nhất", - "leastUsedDesc": "Chọn tài khoản ít được sử dụng gần đây nhất", - "costOpt": "Lựa chọn chi phí", - "costOptDesc": "Ưu tiên tài khoản có sẵn rẻ nhất", - "resetAware": "Đặt lại RR nhận biết", - "resetAwareDesc": "Ưu tiên các tài khoản có hạn ngạch còn lại tốt và thời gian đặt lại gần hơn", - "strictRandom": "Strict Random", - "strictRandomDesc": "Shuffle deck — uses each account once before reshuffling", - "stickyLimit": "Giới hạn dính", - "stickyLimitDesc": "Cuộc gọi trên mỗi tài khoản trước khi chuyển đổi", - "modelAliases": "Bí danh mẫu", + "randomDesc": "Một tài khoản ngẫu nhiên cho mỗi yêu cầu", + "leastUsed": "Ít sử dụng nhất", + "leastUsedDesc": "Chọn tài khoản đã lâu không được sử dụng nhất", + "costOpt": "Tối ưu chi phí", + "costOptDesc": "Ưu tiên tài khoản khả dụng rẻ nhất", + "resetAware": "RR có nhận biết thời điểm đặt lại", + "resetAwareDesc": "Ưu tiên các tài khoản có hạn ngạch còn lại ở mức tốt và thời điểm đặt lại sớm hơn", + "strictRandom": "Ngẫu nhiên nghiêm ngặt", + "strictRandomDesc": "Trộn bộ bài — sử dụng mỗi tài khoản một lần trước khi trộn lại", + "stickyLimit": "Sticky Limit", + "stickyLimitDesc": "Số cuộc gọi trên mỗi tài khoản trước khi chuyển sang tài khoản khác khi cơ chế dự phòng tài khoản toàn cầu sử dụng luân phiên", + "modelAliases": "Bí danh mô hình", "modelAliasesTitle": "Bí danh mô hình", - "modelAliasesDesc": "Remap model names using exact matches or wildcard patterns.", - "addCustomAlias": "Thêm Bí Danh Tùy Chỉnh", - "deprecatedModelId": "ID mô hình ngừng sử dụng", + "modelAliasesDesc": "Ánh xạ lại tên mô hình bằng cách khớp chính xác hoặc mẫu ký tự đại diện.", + "addCustomAlias": "Thêm bí danh tùy chỉnh", + "deprecatedModelId": "ID mô hình không còn được hỗ trợ", "newModelId": "ID mô hình mới", - "customAliases": "Bí Danh Tùy Chỉnh", - "builtInAliases": "Bí Danh Tích Hợp", - "backgroundDegradationTitle": "Giảm Cấp Tác Vụ Nền", - "backgroundDegradationDesc": "Tự động phát hiện tác vụ nền (tiêu đề, tóm tắt) và chuyển hướng sang mô hình rẻ hơn", - "enableDegradation": "Bật Giảm Cấp Nền", - "enableDegradationHint": "Khi bật, các tác vụ nền như tạo tiêu đề và tóm tắt sẽ tự động được chuyển hướng sang các mô hình rẻ hơn", - "tasksDetected": "Tác vụ được phát hiện", - "degradationMap": "Bản Đồ Giảm Cấp Mô Hình", + "customAliases": "Bí danh tùy chỉnh", + "builtInAliases": "Bí danh có sẵn", + "backgroundDegradationTitle": "Hạ cấp tác vụ nền", + "backgroundDegradationDesc": "Tự động phát hiện các tác vụ nền (tiêu đề, tóm tắt) và định tuyến đến các mô hình rẻ hơn", + "enableDegradation": "Kích hoạt hạ cấp tác vụ nền", + "enableDegradationHint": "Khi được kích hoạt, các tác vụ chạy nền như tạo tiêu đề và tóm tắt sẽ tự động được định tuyến đến các mô hình rẻ hơn", + "tasksDetected": "Các tác vụ được phát hiện", + "degradationMap": "Ánh xạ hạ cấp mô hình", "premiumModel": "Mô hình cao cấp", "cheapModel": "Mô hình giá rẻ", - "detectionPatterns": "Mẫu Phát Hiện", - "newPattern": "vd: \"tạo tiêu đề\"", - "aliasPatternPlaceholder": "Claude-sonnet-*", - "aliasTargetPlaceholder": "Claude-sonnet-4-20250514", - "pattern": "mẫu", + "detectionPatterns": "Mẫu phát hiện", + "newPattern": "Ví dụ: \"tạo một tiêu đề\"", + "aliasPatternPlaceholder": "claude-sonnet-*", + "aliasTargetPlaceholder": "claude-sonnet-4-20250514", + "pattern": "Mẫu", "targetModel": "Mô hình mục tiêu", "add": "+ Thêm", "session": "Phiên", "sessionDetailsAria": "Chi tiết phiên", "status": "Trạng thái", "authenticated": "Đã xác thực", - "guest": "khách", + "guest": "Khách", "loginTime": "Thời gian đăng nhập", - "sessionAge": "Tuổi phiên", + "sessionAge": "Thời lượng phiên", "browser": "Trình duyệt", "clearLocalData": "Xóa dữ liệu cục bộ", "logout": "Đăng xuất", - "clearLocalDataConfirm": "Xóa tất cả dữ liệu cục bộ? Điều này sẽ thiết lập lại tùy chọn của bạn.", + "clearLocalDataConfirm": "Xóa tất cả dữ liệu cục bộ? Thao tác này sẽ đặt lại các tùy chọn của bạn.", "unknown": "Không xác định", "systemActor": "hệ thống", "ipAccessControl": "Kiểm soát truy cập IP", "ipAccessControlDesc": "Chặn hoặc cho phép các địa chỉ IP cụ thể", - "ipModeDisabled": "Đã tắt", + "ipModeDisabled": "Tắt", "ipModeBlacklist": "Danh sách đen", "ipModeWhitelist": "Danh sách trắng", - "ipModeWhitelistPriority": "Ưu tiên WL", + "ipModeWhitelistPriority": "Ưu tiên danh sách cho phép", "addIpAddress": "Thêm địa chỉ IP", "ipAddressPlaceholder": "192.168.1.0/24 hoặc 10.0.*.*", "block": "+ Chặn", "allow": "+ Cho phép", "blocked": "Đã chặn ({count})", "allowed": "Được phép ({count})", - "temporaryBans": "Lệnh cấm tạm thời ({count})", - "minLeft": "{min} phút còn lại", - "auditLog": "Nhật ký kiểm tra", + "temporaryBans": "Cấm tạm thời ({count})", + "minLeft": "Còn lại {min} phút", + "auditLog": "Nhật ký kiểm toán", "searchAuditLogs": "Tìm kiếm nhật ký kiểm tra...", "failedLoadAuditLog": "Không tải được nhật ký kiểm tra", "noAuditEvents": "Không tìm thấy sự kiện kiểm tra nào", - "action": "hành động", - "actor": "diễn viên", + "action": "Hành động", + "actor": "Tác nhân", "details": "Chi tiết", - "time": "thời gian", + "time": "Thời gian", "fallbackChainsTitle": "Chuỗi dự phòng", - "fallbackChainsDesc": "Xác định thứ tự dự phòng của nhà cung cấp cho mỗi mô hình", + "fallbackChainsDesc": "Xác định thứ tự dự phòng giữa các nhà cung cấp cho từng mô hình", "addChain": "+ Thêm chuỗi", - "modelName": "Tên mẫu", - "modelNamePlaceholder": "Claude-sonnet-4-20250514", - "providersCommaSeparated": "Nhà cung cấp (được phân tách bằng dấu phẩy, theo thứ tự ưu tiên)", - "providersCommaSeparatedPlaceholder": "nhân loại, openai, song tử", + "modelName": "Tên mô hình", + "modelNamePlaceholder": "claude-sonnet-4-20250514", + "providersCommaSeparated": "Nhà cung cấp (cách nhau bằng dấu phẩy, theo thứ tự ưu tiên)", + "providersCommaSeparatedPlaceholder": "anthropic, openai, gemini", "createChain": "Tạo chuỗi", "noFallbackChains": "Không có chuỗi dự phòng", - "noFallbackChainsDesc": "Tạo một chuỗi để xác định thứ tự dự phòng của nhà cung cấp cho một mô hình.", - "loadingFallbackChains": "Đang tải chuỗi dự phòng...", + "noFallbackChainsDesc": "Tạo một chuỗi để xác định thứ tự dự phòng giữa các nhà cung cấp cho một mô hình.", + "loadingFallbackChains": "Đang tải các chuỗi dự phòng...", "deleteChainConfirm": "Xóa chuỗi dự phòng cho \"{model}\"?", "chainCreated": "Đã tạo chuỗi cho {model}", "chainDeleted": "Đã xóa chuỗi cho {model}", - "failedCreateChain": "Không tạo được chuỗi", - "failedDeleteChain": "Không thể xóa chuỗi", + "failedCreateChain": "Tạo chuỗi thất bại", + "failedDeleteChain": "Xóa chuỗi thất bại", "deleteChain": "Xóa chuỗi", - "fillModelAndProviders": "Vui lòng điền tên model và nhà cung cấp", + "fillModelAndProviders": "Vui lòng điền tên mô hình và nhà cung cấp", "addAtLeastOneProvider": "Thêm ít nhất một nhà cung cấp", - "comboDefaultsTitle": "Mặc định kết hợp", - "comboDefaultsGuideTitle": "Cách điều chỉnh mặc định kết hợp", - "comboDefaultsGuideHint1": "Giữ số lần thử ở mức thấp trong các luồng có độ trễ thấp; chỉ tăng thời gian chờ cho các tác vụ tạo dài.", + "comboDefaultsTitle": "Giá trị mặc định của tổ hợp", + "comboDefaultsGuideTitle": "Cách điều chỉnh giá trị mặc định của tổ hợp", + "comboDefaultsGuideHint1": "Giữ số lần thử lại ở mức thấp trong các luồng có độ trễ thấp; chỉ tăng thời gian chờ cho các tác vụ tạo nội dung dài.", "comboDefaultsGuideHint2": "Sử dụng ghi đè nhà cung cấp khi một nhà cung cấp cần hành vi hết thời gian chờ/thử lại khác với mặc định chung.", - "globalComboConfig": "Cấu hình kết hợp toàn cầu", + "globalComboConfig": "Cấu hình tổ hợp toàn cục", "defaultStrategy": "Chiến lược mặc định", - "defaultStrategyDesc": "Áp dụng cho các combo mới không có chiến lược rõ ràng", - "comboStrategyAria": "Chiến lược kết hợp", + "defaultStrategyDesc": "Áp dụng cho các tổ hợp mới chưa được chỉ định chiến lược và đồng bộ với định tuyến dự phòng toàn cục của tài khoản", + "comboStrategyAria": "Chiến lược tổ hợp", "priority": "Ưu tiên", "weighted": "Có trọng số", "contextRelay": "Context Relay", - "contextRelayDesc": "Hands off context between providers with automatic summarization", + "contextRelayDesc": "Định tuyến kiểu ưu tiên với việc tự động chuyển giao ngữ cảnh khi xảy ra xoay vòng tài khoản", "maxRetriesLabel": "Số lần thử lại tối đa", "retryDelayLabel": "Độ trễ thử lại (ms)", "timeoutLabel": "Thời gian chờ (ms)", "healthCheck": "Kiểm tra sức khỏe", "healthCheckDesc": "Kiểm tra trước tính khả dụng của nhà cung cấp", "trackMetrics": "Theo dõi số liệu", - "trackMetricsDesc": "Ghi lại số liệu yêu cầu trên mỗi kết hợp", - "providerOverrides": "Ghi đè nhà cung cấp", - "providerOverridesDesc": "Ghi đè thời gian chờ và thử lại trên mỗi nhà cung cấp. Cài đặt nhà cung cấp ghi đè mặc định chung.", - "providerMaxRetriesAria": "{provider} số lần thử lại tối đa", - "providerTimeoutAria": "{provider} hết thời gian chờ mili giây", - "removeProviderOverrideAria": "Xóa ghi đè {provider}", + "trackMetricsDesc": "Ghi lại số liệu yêu cầu cho từng tổ hợp", + "providerOverrides": "Ghi đè theo nhà cung cấp", + "providerOverridesDesc": "Ghi đè thời gian chờ và số lần thử lại cho từng nhà cung cấp. Cài đặt nhà cung cấp sẽ ghi đè mặc định chung.", + "providerMaxRetriesAria": "Số lần thử lại tối đa của {provider}", + "providerTimeoutAria": "Thời gian chờ của {provider} (ms)", + "removeProviderOverrideAria": "Xóa ghi đè của {provider}", "newProviderNamePlaceholder": "ví dụ: google, openai...", "newProviderNameAria": "Tên nhà cung cấp mới", - "retries": "thử lại", - "ms": "cô", - "saveComboDefaults": "Lưu mặc định kết hợp", - "maxNestingDepth": "Độ sâu lồng tối đa", - "concurrencyPerModel": "Đồng thời / Mô hình", - "queueTimeout": "Hết thời gian xếp hàng (ms)", - "contextRelayHandoffThreshold": "Handoff Threshold", - "contextRelayMaxMessages": "Max Messages For Summary", - "contextRelaySummaryModel": "Summary Model", - "contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.", + "retries": "lần thử lại", + "ms": "ms", + "saveComboDefaults": "Lưu giá trị mặc định của tổ hợp", + "maxNestingDepth": "Độ sâu lồng nhau tối đa", + "concurrencyPerModel": "Đồng thời trên mỗi mô hình", + "queueTimeout": "Thời gian chờ hàng đợi (ms)", + "contextRelayHandoffThreshold": "Ngưỡng chuyển giao", + "contextRelayMaxMessages": "Số lượng tin nhắn tối đa để tóm tắt", + "contextRelaySummaryModel": "Mô hình tóm tắt", + "contextRelayProviderNote": "Context Relay hiện tạo các lượt chuyển giao cho tài khoản Codex và sử dụng các giá trị này làm giá trị mặc định toàn cục cho các tổ hợp mới hoặc chưa được cấu hình.", "providerProfiles": "Hồ sơ nhà cung cấp", - "providerProfilesDesc": "Cài đặt khả năng phục hồi riêng biệt cho các nhà cung cấp OAuth (dựa trên phiên) và Khóa API (được đo lường). Nhà cung cấp OAuth có ngưỡng chặt chẽ hơn do giới hạn tốc độ thấp hơn.", + "providerProfilesDesc": "Cài đặt khả năng phục hồi riêng biệt cho các nhà cung cấp OAuth (dựa trên phiên) và API Key (tính theo mức sử dụng). Các nhà cung cấp OAuth có các ngưỡng nghiêm ngặt hơn do giới hạn tốc độ thấp hơn.", "oauthProviders": "Nhà cung cấp OAuth", - "apiKeyProviders": "Nhà cung cấp khóa API", - "transientCooldown": "Thời gian hồi chiêu thoáng qua", - "rateLimitCooldown": "Thời gian hồi chiêu giới hạn tốc độ", - "maxBackoffLevel": "Mức chờ đợi tối đa", + "apiKeyProviders": "Nhà cung cấp API Key", + "transientCooldown": "Thời gian chờ tạm thời", + "rateLimitCooldown": "Thời gian chờ giới hạn tốc độ", + "maxBackoffLevel": "Mức giãn cách tối đa", "cbThreshold": "Ngưỡng CB", "cbResetTime": "Thời gian đặt lại CB", - "rateLimiting": "Giới hạn tỷ lệ", - "rateLimitingDesc": "Nhà cung cấp Khóa API được tự động giới hạn tỷ lệ với các giá trị mặc định an toàn. Các giới hạn được học từ tiêu đề phản hồi và điều chỉnh theo thời gian.", + "rateLimiting": "Giới hạn tốc độ", + "rateLimitingDesc": "Các nhà cung cấp API Key được tự động giới hạn tốc độ với các giá trị mặc định an toàn. Các giới hạn được suy ra từ header phản hồi và tự động điều chỉnh theo thời gian.", "defaultSafetyNet": "Mạng lưới an toàn mặc định", - "rpm": "vòng/phút", + "rpm": "RPM", "minGap": "Khoảng cách tối thiểu", - "maxConcurrent": "Đồng thời tối đa", - "activeLimiters": "Bộ hạn chế hoạt động", - "noActiveLimiters": "Chưa có giới hạn tỷ lệ hoạt động nào.", - "reservoir": "Hồ chứa nước", + "maxConcurrent": "Số lượng đồng thời tối đa", + "activeLimiters": "Bộ giới hạn đang hoạt động", + "noActiveLimiters": "Chưa có bộ giới hạn tốc độ nào đang hoạt động.", + "reservoir": "Dung lượng dự trữ", "running": "Đang chạy", - "queued": "Đã xếp hàng", + "queued": "Trong hàng đợi", "circuitBreakers": "Bộ ngắt mạch", "breakerStateClosed": "Đã đóng", "breakerStateOpen": "Mở", "breakerStateHalfOpen": "Nửa mở", - "tripped": "{count} bị vấp", - "healthy": "{count} khỏe mạnh", + "tripped": "{count} đã bị ngắt", + "healthy": "{count} hoạt động tốt", "resetAll": "Đặt lại tất cả", - "noCircuitBreakers": "Chưa có bộ ngắt mạch nào hoạt động. Chúng được tạo tự động khi các yêu cầu chảy qua đường dẫn kết hợp.", + "noCircuitBreakers": "Chưa có bộ ngắt mạch nào hoạt động. Chúng được tạo tự động khi các yêu cầu đi qua quy trình xử lý tổ hợp.", "failures": "{count} lỗi", "policiesLocked": "Chính sách & Mã định danh bị khóa", - "allOperational": "Tất cả các hệ thống đều hoạt động - không có khóa hoặc cầu dao bị ngắt", + "allOperational": "Tất cả hệ thống đang hoạt động bình thường — không có tình trạng khóa hoặc bộ ngắt mạch nào bị kích hoạt", "loadingPolicies": "Đang tải chính sách...", - "lockedIdentifiers": "Số nhận dạng bị khóa", + "lockedIdentifiers": "Mã định danh bị khóa", "unlockedIdentifier": "Đã mở khóa: {identifier}", - "sinceDate": "kể từ {date}", - "forceUnlock": "Buộc mở khóa", + "sinceDate": "từ {date}", + "forceUnlock": "Bắt buộc mở khóa", "unlocking": "Đang mở khóa...", - "failedUnlock": "Không thể mở khóa", - "failedLoadWithStatus": "Không tải được: {status}", - "failedLoadResilience": "Không tải được trạng thái phục hồi", - "saveFailed": "Lưu không thành công", - "resetFailed": "Đặt lại không thành công", - "loadingResilience": "Đang tải trạng thái phục hồi...", + "failedUnlock": "Mở khóa thất bại", + "failedLoadWithStatus": "Không thể tải: {status}", + "failedLoadResilience": "Không thể tải trạng thái khả năng phục hồi", + "saveFailed": "Lưu thất bại", + "resetFailed": "Đặt lại thất bại", + "loadingResilience": "Đang tải trạng thái khả năng phục hồi...", "retry": "Thử lại", - "systemStorage": "Hệ thống & Lưu trữ", + "systemStorage": "Lưu trữ", "allDataLocal": "Tất cả dữ liệu được lưu trữ cục bộ trên máy của bạn", "databasePath": "Đường dẫn cơ sở dữ liệu", "exportDatabase": "Xuất cơ sở dữ liệu", @@ -4984,804 +5513,1097 @@ "importDatabase": "Nhập cơ sở dữ liệu", "confirmDbImport": "Xác nhận nhập cơ sở dữ liệu", "confirmDbImportDesc": "Thao tác này sẽ thay thế tất cả dữ liệu hiện tại bằng nội dung từ {file}. Một bản sao lưu sẽ được tạo tự động trước khi nhập.", - "yesImport": "Có, nhập khẩu", - "lastBackup": "Sao lưu lần cuối", - "noBackupYet": "Chưa có bản sao lưu nào", + "yesImport": "Có, nhập", + "lastBackup": "Bản sao lưu gần nhất", + "noBackupYet": "Chưa có bản sao lưu", "backupNow": "Sao lưu ngay", "backupRestore": "Sao lưu & Khôi phục", - "viewBackups": "Xem bản sao lưu", + "viewBackups": "Xem các bản sao lưu", "hide": "Ẩn", - "backupRetentionDesc": "Ảnh chụp nhanh cơ sở dữ liệu được tạo tự động trước khi khôi phục và cứ sau 15 phút khi dữ liệu thay đổi. Lưu giữ: 24 giờ + 30 lần sao lưu hàng ngày với chế độ xoay thông minh.", - "loadingBackups": "Đang tải bản sao lưu...", - "noBackupsYet": "Chưa có bản sao lưu nào. Bản sao lưu sẽ được tạo tự động khi dữ liệu thay đổi.", - "backupsAvailable": "{count} bản sao lưu có sẵn", + "backupRetentionDesc": "Ảnh chụp nhanh cơ sở dữ liệu được tạo tự động trước khi khôi phục và mỗi 15 phút khi dữ liệu thay đổi. Thời gian lưu giữ: 24 bản sao lưu hàng giờ + 30 bản sao lưu hàng ngày với cơ chế xoay vòng thông minh.", + "loadingBackups": "Đang tải các bản sao lưu...", + "noBackupsYet": "Chưa có bản sao lưu nào. Các bản sao lưu sẽ được tạo tự động khi dữ liệu thay đổi.", + "backupsAvailable": "Hiện có {count} bản sao lưu", "refresh": "Làm mới", "confirm": "Xác nhận?", "yes": "Có", "no": "Không", "restore": "Khôi phục", - "invalidFileType": "Loại tệp không hợp lệ. Chỉ các tệp .sqlite được chấp nhận.", - "exportFailed": "Xuất không thành công", - "exportFailedWithError": "Xuất không thành công: {error}", - "fullExportFailedWithError": "Xuất toàn bộ không thành công: {error}", + "invalidFileType": "Loại tệp không hợp lệ. Chỉ chấp nhận các tệp .sqlite.", + "exportFailed": "Xuất thất bại", + "exportFailedWithError": "Xuất thất bại: {error}", + "fullExportFailedWithError": "Xuất toàn bộ thất bại: {error}", "backupCreated": "Đã tạo bản sao lưu: {file}", - "restoreSuccess": "Đã khôi phục! {connections} kết nối, nút {nodes}, tổ hợp {combos}, khóa API {apiKeys}.", - "importSuccess": "Cơ sở dữ liệu đã được nhập! {connections} kết nối, nút {nodes}, tổ hợp {combos}, khóa API {apiKeys}.", + "restoreSuccess": "Đã khôi phục! {connections} kết nối, {nodes} nút, {combos} tổ hợp, {apiKeys} khóa API.", + "importSuccess": "Đã nhập cơ sở dữ liệu! {connections} kết nối, {nodes} nút, {combos} tổ hợp, {apiKeys} khóa API.", "minutesAgo": "{count} phút trước", "hoursAgo": "{count} giờ trước", - "daysAgo": "{count}ngày trước", - "backupReasonManual": "hướng dẫn sử dụng", - "backupReasonPreRestore": "khôi phục trước", - "connectionsCount": "{count, plural, one {# connection} other {# connections}}", - "noChangesSinceBackup": "Không có thay đổi nào kể từ lần sao lưu cuối cùng", - "backupFailed": "Sao lưu không thành công", - "restoreFailed": "Khôi phục không thành công", - "importFailed": "Nhập không thành công", + "daysAgo": "{count} ngày trước", + "backupReasonManual": "thủ công", + "backupReasonPreRestore": "trước khi khôi phục", + "connectionsCount": "{count, plural, one {# kết nối} other {# kết nối}}", + "noChangesSinceBackup": "Không có thay đổi nào kể từ bản sao lưu cuối cùng", + "backupFailed": "Sao lưu thất bại", + "restoreFailed": "Khôi phục thất bại", + "importFailed": "Nhập thất bại", "errorDuringRestore": "Đã xảy ra lỗi trong quá trình khôi phục", "errorDuringImport": "Đã xảy ra lỗi trong quá trình nhập", - "modelPricing": "Giá mẫu", - "modelPricingDesc": "Định cấu hình mức chi phí cho mỗi mô hình • Tất cả mức giá bằng mã thông báo $/1 triệu", - "registry": "Đăng ký", + "modelPricing": "Giá mô hình", + "modelPricingDesc": "Định cấu hình mức chi phí cho mỗi mô hình • Tất cả mức giá tính theo $/1M token", + "registry": "Danh mục", "priced": "Đã định giá", "searchProvidersModels": "Tìm kiếm nhà cung cấp hoặc mô hình...", "showAll": "Hiển thị tất cả", "noProvidersMatch": "Không có nhà cung cấp nào phù hợp với tìm kiếm của bạn.", - "howPricingWorks": "Cách thức hoạt động của giá", - "cacheWrite": "Ghi bộ nhớ đệm", - "unsaved": "chưa được lưu", + "howPricingWorks": "Cách thức tính giá", + "cacheWrite": "Ghi cache", + "unsaved": "chưa lưu", "resetDefaults": "Đặt lại mặc định", "saveProvider": "Lưu nhà cung cấp", - "model": "người mẫu", + "model": "Mô hình", "models": "mô hình", - "moreProviders": "{count} nhà cung cấp khác", - "withPricing": "với giá được cấu hình", - "policiesCircuitBreakers": "Chính sách & Bộ ngắt mạch", + "moreProviders": "{count} nhà cung cấp khác nữa", + "withPricing": "đã cấu hình giá", + "policiesCircuitBreakers": "Chính sách & bộ ngắt mạch", "activeIssuesDetected": "Đã phát hiện sự cố đang diễn ra", "off": "Tắt", - "resetPricingConfirm": "Đặt lại tất cả giá cho {provider} về mặc định?", - "pricingDescInput": "Đầu vào: mã thông báo được gửi đến mô hình", - "pricingDescOutput": "Đầu ra: mã thông báo được tạo", - "pricingDescCached": "Đã lưu vào bộ nhớ đệm: đầu vào được sử dụng lại (~50% tốc độ đầu vào)", - "pricingDescReasoning": "Lý luận: mã thông báo suy nghĩ (quay lại Đầu ra)", - "pricingDescCacheWrite": "Ghi bộ đệm: tạo các mục bộ đệm (quay lại Đầu vào)", - "pricingDescFormula": "Chi phí = (đầu vào × tốc độ đầu vào) + (đầu ra × tốc độ đầu ra) + (được lưu vào bộ nhớ đệm × tốc độ được lưu vào bộ nhớ cache) trên một triệu mã thông báo.", + "resetPricingConfirm": "Đặt lại tất cả giá của {provider} về mặc định?", + "pricingDescInput": "Đầu vào: token được gửi đến mô hình", + "pricingDescOutput": "Đầu ra: token được tạo", + "pricingDescCached": "Cache: đầu vào được tái sử dụng (~50% mức giá đầu vào)", + "pricingDescReasoning": "Suy luận: token suy nghĩ (dự phòng về Đầu ra)", + "pricingDescCacheWrite": "Ghi cache: tạo các mục cache (dự phòng về Đầu vào)", + "pricingDescFormula": "Chi phí = (input × input_rate) + (output × output_rate) + (cached × cached_rate) trên một triệu token.", "pricingSettingsTitle": "Cài đặt giá", "totalModels": "Tổng số mô hình", "active": "Đang hoạt động", "costCalculation": "Tính toán chi phí", - "costCalculationDesc": "Chi phí được tính toán dựa trên mức sử dụng mã thông báo và mức giá được định cấu hình cho từng mô hình.", + "costCalculationDesc": "Chi phí được tính toán dựa trên mức sử dụng token và mức giá được định cấu hình cho từng mô hình.", "pricingFormat": "Định dạng giá", - "pricingFormatDesc": "Tất cả các mức giá đều tính bằng token $/1 triệu (đô la trên một triệu token).", - "tokenTypes": "Các loại mã thông báo", - "inputTokenDesc": "Mã thông báo nhắc nhở tiêu chuẩn", - "outputTokenDesc": "Mã thông báo hoàn thành/phản hồi", - "cachedTokenDesc": "Mã thông báo đầu vào được lưu trong bộ nhớ đệm (thường là 50% tốc độ đầu vào)", - "reasoningTokenDesc": "Mã thông báo lý luận/suy nghĩ đặc biệt (dự phòng tốc độ đầu ra)", - "cacheCreationTokenDesc": "Mã thông báo được sử dụng để tạo mục nhập bộ đệm (dự phòng tốc độ đầu vào)", - "customPricingNote": "Bạn có thể ghi đè giá mặc định cho các kiểu máy cụ thể. Ghi đè tùy chỉnh được ưu tiên hơn giá được tự động phát hiện.", + "pricingFormatDesc": "Tất cả mức giá đều tính bằng $/1M token (đô la cho mỗi một triệu token).", + "tokenTypes": "Các loại token", + "inputTokenDesc": "Token prompt tiêu chuẩn", + "outputTokenDesc": "Token hoàn tất/phản hồi", + "cachedTokenDesc": "Token đầu vào được cache (thường bằng 50% mức giá đầu vào)", + "reasoningTokenDesc": "Token suy luận/suy nghĩ đặc biệt (dự phòng theo mức giá đầu ra)", + "cacheCreationTokenDesc": "Token được sử dụng để tạo mục cache (dự phòng theo mức giá đầu vào)", + "customPricingNote": "Bạn có thể ghi đè giá mặc định cho các mô hình cụ thể. Các ghi đè tùy chỉnh được ưu tiên hơn giá được tự động phát hiện.", "editPricing": "Chỉnh sửa giá", "viewFullDetails": "Xem chi tiết đầy đủ", "themeCoral": "San hô", - "adaptiveVolumeRouting": "Adaptive Volume Routing", - "adaptiveVolumeRoutingDesc": "Scale connections dynamically based on payload volume and throughput pressure.", - "lkgpToggleTitle": "Last Known Good Provider (LKGP)", - "lkgpToggleDesc": "When enabled, the router remembers which provider last served a successful response and tries it first on subsequent requests.", - "clearLkgpCache": "Clear LKGP Cache", - "lkgpCacheCleared": "LKGP cache cleared successfully", - "lkgpCacheClearFailed": "Failed to clear LKGP cache", - "days": "Days", - "lkgp": "LKGP Mode", - "lkgpDesc": "Last Known Good Provider (Predictable resilience)", - "maintenance": "Maintenance", - "purgeExpiredLogs": "Purge Expired Logs", - "purgeLogsFailed": "Failed to purge logs", - "contextOpt": "Context Optimized", - "contextOptDesc": "Routes based on context window requirements and conversation length", - "priorityDesc": "Sequential fallback - tries provider 1 first, then provider 2, and so on", - "weightedDesc": "Distributes traffic by percentage weights across providers", - "modelRoutingTitle": "Model Routing Rules", - "modelRoutingDesc": "Automatically route models to specific combos using glob patterns", - "addRule": "Add Rule", - "routeToCombo": "Route to Combo", - "selectCombo": "Select combo...", - "priorityHint": "Higher = checked first. Use 10+ for specific patterns.", - "patternHint": "Use * for any chars, ? for single char. Case-insensitive.", - "noRoutingRules": "No routing rules configured. Requests use the global combo by default.", - "routingRuleHint": "Add a rule like claude-opus* -> frontier-combo to automatically route requests.", - "deleteRoutingRule": "Delete this model routing rule?", - "exactMatchMode": "Exact Match", - "wildcardPatternMode": "Wildcard Pattern", - "exactMatchModeDesc": "Use exact aliases for deprecated or renamed model IDs.", - "wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.", - "noExactAliasesConfigured": "No exact-match aliases configured.", - "wildcardRulesTitle": "Wildcard Rules", - "noWildcardAliasesConfigured": "No wildcard aliases configured.", - "overview": "Overview", - "unknownError": "Unknown Error", - "pricingSourceLiteLLM": "Pricing Source Lite Llm", - "clearSyncedPricingConfirm": "Clear Synced Pricing Confirm", - "clearSyncedPricingFailed": "Clear Synced Pricing Failed", - "pricingSourceUser": "Pricing Source User", - "pageDescription": "Page Description", - "pricingSyncStatus": "Pricing Sync Status", - "whitelist": "Whitelist", - "syncDisabled": "Sync Disabled", - "pricingLoadFailed": "Pricing Load Failed", - "pricingSyncDescription": "Pricing Sync Description", - "clearSyncedPricingSuccess": "Clear Synced Pricing Success", - "clearSyncedPricingFailedWithReason": "Không xóa được giá: {reason}", - "pricingSourceDefault": "Pricing Source Default", - "pricingSyncSuccess": "Pricing Sync Success", - "enableSyncError": "Enable Sync Error", - "syncEnabled": "Sync Enabled", - "blacklist": "Blacklist", - "pricingSourceModelsDev": "Pricing Source Models Dev", - "syncedModels": "Synced Models", - "budget": "Budget", - "pricingSyncTitle": "Pricing Sync Title", - "pricingResetFailedWithReason": "Không đặt lại được giá: {reason}", - "tab": "Tab", + "adaptiveVolumeRouting": "Định tuyến lưu lượng thích ứng", + "adaptiveVolumeRoutingDesc": "Tự động điều chỉnh số lượng kết nối dựa trên khối lượng dữ liệu tải và áp lực thông lượng.", + "lkgpToggleTitle": "Nhà cung cấp hoạt động tốt gần đây nhất (LKGP)", + "lkgpToggleDesc": "Khi được bật, bộ định tuyến sẽ ghi nhớ nhà cung cấp nào đã phản hồi thành công gần nhất và thử nhà cung cấp đó trước tiên trong các yêu cầu tiếp theo.", + "clearLkgpCache": "Xóa cache LKGP", + "lkgpCacheCleared": "Đã xóa cache LKGP thành công", + "lkgpCacheClearFailed": "Không thể xóa cache LKGP", + "days": "Ngày", + "lkgp": "Chế độ LKGP", + "lkgpDesc": "Nhà cung cấp hoạt động tốt gần đây nhất (Khả năng phục hồi có thể dự đoán)", + "maintenance": "Bảo trì", + "purgeExpiredLogs": "Dọn sạch log đã hết hạn", + "purgeLogsFailed": "Không thể dọn sạch log", + "contextOpt": "Tối ưu hóa ngữ cảnh", + "contextOptDesc": "Định tuyến dựa trên yêu cầu cửa sổ ngữ cảnh và độ dài hội thoại", + "priorityDesc": "Dự phòng tuần tự - thử nhà cung cấp 1 trước, sau đó là nhà cung cấp 2, v.v.", + "weightedDesc": "Phân phối lưu lượng theo tỷ trọng phần trăm giữa các nhà cung cấp", + "modelRoutingTitle": "Quy tắc định tuyến mô hình", + "modelRoutingDesc": "Tự động định tuyến các mô hình đến các combo cụ thể bằng cách sử dụng các mẫu glob", + "addRule": "Thêm quy tắc", + "routeToCombo": "Định tuyến đến Combo", + "selectCombo": "Chọn combo...", + "priorityHint": "Cao hơn = được kiểm tra trước. Sử dụng 10+ cho các mẫu cụ thể.", + "patternHint": "Sử dụng * cho bất kỳ ký tự nào, ? cho một ký tự đơn. Không phân biệt chữ hoa chữ thường.", + "noRoutingRules": "Chưa có quy tắc định tuyến nào được cấu hình. Theo mặc định, các yêu cầu sẽ sử dụng tổ hợp toàn cục.", + "routingRuleHint": "Thêm một quy tắc như claude-opus* -> frontier-combo để tự động định tuyến các yêu cầu.", + "deleteRoutingRule": "Xóa quy tắc định tuyến mô hình này?", + "exactMatchMode": "Khớp chính xác", + "wildcardPatternMode": "Mẫu ký tự đại diện", + "exactMatchModeDesc": "Sử dụng các bí danh chính xác cho các ID mô hình đã ngừng hỗ trợ hoặc được đổi tên.", + "wildcardPatternModeDesc": "Sử dụng bí danh ký tự đại diện với * và ? khi một nhóm mô hình cần được ánh xạ tới một mục tiêu.", + "noExactAliasesConfigured": "Chưa cấu hình bí danh khớp chính xác nào.", + "wildcardRulesTitle": "Quy tắc ký tự đại diện", + "noWildcardAliasesConfigured": "Chưa cấu hình bí danh ký tự đại diện nào.", + "overview": "Tổng quan", + "unknownError": "Lỗi không xác định", + "pricingSourceLiteLLM": "LiteLLM (Cộng đồng)", + "clearSyncedPricingConfirm": "Xóa tất cả dữ liệu giá đã đồng bộ hóa? Mặc định của nhà cung cấp sẽ được sử dụng thay thế.", + "clearSyncedPricingFailed": "Không thể xóa giá đã đồng bộ hóa", + "pricingSourceUser": "Ghi đè của người dùng", + "pageDescription": "Quản lý cài đặt ứng dụng, bí danh mô hình, giá cả và quy tắc định tuyến", + "pricingSyncStatus": "Trạng thái đồng bộ hóa", + "whitelist": "Danh sách trắng", + "syncDisabled": "Đã tắt đồng bộ hóa", + "pricingLoadFailed": "Không thể tải dữ liệu giá", + "pricingSyncDescription": "Tự động đồng bộ hóa giá mô hình từ các nguồn bên ngoài để giữ cho việc tính toán chi phí luôn chính xác", + "clearSyncedPricingSuccess": "Đã xóa dữ liệu giá đã đồng bộ hóa", + "clearSyncedPricingFailedWithReason": "Không thể xóa giá: {reason}", + "pricingSourceDefault": "Mặc định tích hợp sẵn", + "pricingSyncSuccess": "Đồng bộ hóa giá thành công", + "enableSyncError": "Không thể thay đổi trạng thái đồng bộ hóa giá", + "syncEnabled": "Đã bật đồng bộ hóa", + "blacklist": "Danh sách đen", + "pricingSourceModelsDev": "Models.dev", + "syncedModels": "Mô hình đã đồng bộ hóa", + "budget": "Ngân sách", + "pricingSyncTitle": "Đồng bộ hóa giá", + "pricingResetFailedWithReason": "Không thể đặt lại giá: {reason}", + "tab": "Thẻ", "pricingSavedProvider": "Đã lưu giá cho {provider}", - "pricingSyncFailed": "Pricing Sync Failed", - "pricingSaveFailedWithReason": "Không lưu được giá: {reason}", - "pricingResetProvider": "Đặt lại giá cho {provider}", - "nextSync": "Next Sync", - "pricingSyncFailedWithReason": "Đồng bộ hóa giá không thành công: {reason}", - "clearSyncedPricing": "Clear Synced Pricing", - "compressionTitle": "Prompt Compression", - "compressionDesc": "Reduce token usage by compressing prompts before sending to providers", - "compressionMode": "Compression Mode", - "compressionModeOff": "Off", - "compressionModeOffDesc": "No compression applied", + "pricingSyncFailed": "Đồng bộ hóa giá thất bại", + "pricingSaveFailedWithReason": "Không thể lưu giá: {reason}", + "pricingResetProvider": "Đã đặt lại giá cho {provider}", + "nextSync": "Lần đồng bộ tiếp theo", + "pricingSyncFailedWithReason": "Đồng bộ hóa giá thất bại: {reason}", + "clearSyncedPricing": "Xóa giá đã đồng bộ hóa", + "compressionTitle": "Nén prompt", + "compressionDesc": "Giảm mức sử dụng token bằng cách nén các prompt trước khi gửi đến các nhà cung cấp", + "compressionMode": "Chế độ nén", + "compressionModeOff": "Tắt", + "compressionModeOffDesc": "Không áp dụng nén", "compressionModeLite": "Lite", - "compressionModeLiteDesc": "Whitespace and blank line reduction", - "compressionModeStandard": "Standard (Caveman)", - "compressionModeStandardDesc": "Rule-based compression with 30+ patterns, preserves code blocks and URLs", - "compressionModeAggressive": "Aggressive", - "compressionModeAggressiveDesc": "Summarization + tool result compression + progressive aging for maximum savings", + "compressionModeLiteDesc": "Giảm khoảng trắng và dòng trống", + "compressionModeStandard": "Tiêu chuẩn (Caveman)", + "compressionModeStandardDesc": "Nén dựa trên quy tắc với hơn 30 mẫu, giữ lại khối mã và URL", + "compressionModeAggressive": "Mạnh", + "compressionModeAggressiveDesc": "Tóm tắt + nén kết quả công cụ + lão hóa lũy tiến để tiết kiệm tối đa", "compressionModeUltra": "Ultra", - "compressionModeUltraDesc": "Maximum compression with all techniques including semantic deduplication", - "compressionAggressiveConfig": "Cấu hình động cơ mạnh mẽ", + "compressionModeUltraDesc": "Cắt tỉa token theo quy tắc kinh nghiệm, có thể dự phòng bằng SLM cục bộ", + "compressionAggressiveConfig": "Cấu hình cơ chế Mạnh", "compressionAggressiveConfigDesc": "Tinh chỉnh tóm tắt, nén công cụ và ngưỡng lão hóa", - "compressionUltraConfig": "Cấu hình Ultra Engine", - "compressionUltraConfigDesc": "Tinh chỉnh việc cắt tỉa heuristic, dự phòng SLM và ngưỡng cho mỗi tin nhắn", - "compressionUltraRate": "Giữ tỷ lệ", + "compressionUltraConfig": "Cấu hình cơ chế Siêu mạnh", + "compressionUltraConfigDesc": "Tinh chỉnh việc cắt tỉa theo quy tắc kinh nghiệm, dự phòng SLM và ngưỡng cho từng tin nhắn", + "compressionUltraRate": "Tỷ lệ giữ lại", "compressionUltraMinScore": "Ngưỡng điểm tối thiểu", - "compressionUltraSlmFallback": "Dự phòng cho tích cực", + "compressionUltraSlmFallback": "Dự phòng sang Mạnh", "compressionUltraModelPath": "Đường dẫn mô hình SLM", "compressionSummarizerEnabled": "Bật trình tóm tắt", - "compressionMaxTokensPerMessage": "Số mã thông báo tối đa cho mỗi tin nhắn", + "compressionMaxTokensPerMessage": "Token tối đa cho mỗi tin nhắn", "compressionMinSavings": "Ngưỡng tiết kiệm tối thiểu", "compressionAgingThresholds": "Ngưỡng lão hóa", - "compressionAgingThresholdsDesc": "Số lượng tin nhắn gần đây được lưu giữ ở mỗi cấp độ cũ (cao hơn = được bảo tồn nhiều hơn)", + "compressionAgingThresholdsDesc": "Số lượng tin nhắn gần đây được giữ lại ở mỗi cấp độ lão hóa (cao hơn = được bảo toàn nhiều hơn)", "compressionToolStrategies": "Chiến lược kết quả công cụ", - "compressionToolStrategiesDesc": "Chuyển đổi chiến lược nén cho các loại kết quả công cụ khác nhau", - "compressionGeneral": "General Settings", - "compressionAutoTrigger": "Auto-Trigger Threshold", + "compressionToolStrategiesDesc": "Bật/tắt chiến lược nén cho các loại kết quả công cụ khác nhau", + "compressionGeneral": "Cài đặt chung", + "compressionAutoTrigger": "Ngưỡng tự động kích hoạt", "compressionCacheTTL": "Cache TTL", - "compressionPreserveSystem": "Preserve System Prompt", - "compressionCavemanConfig": "Caveman Engine Configuration", - "compressionCavemanConfigDesc": "Fine-tune the rule-based compression engine", - "compressionRoles": "Compress Message Roles", - "compressionRoleUser": "User", - "compressionRoleAssistant": "Assistant", - "compressionRoleSystem": "System", - "compressionMinLength": "Minimum Message Length", - "compressionSkipRules": "Skip Compression Rules", - "compressionSkipRulesDesc": "Click rules to skip them during compression", - "compressionPreservePatterns": "Preserve Patterns", - "compressionPreservePatternsDesc": "Regex patterns that are never compressed (one per line)", - "compressionLogTitle": "Compression Log", - "compressionLogEmpty": "No compressed requests yet. Compression stats will appear here when requests are processed with compression enabled.", + "compressionPreserveSystem": "Giữ lại prompt hệ thống", + "compressionCavemanConfig": "Cấu hình động cơ Caveman", + "compressionCavemanConfigDesc": "Tinh chỉnh động cơ nén dựa trên quy tắc", + "compressionRoles": "Nén vai trò tin nhắn", + "compressionRoleUser": "Người dùng", + "compressionRoleAssistant": "Trợ lý", + "compressionRoleSystem": "Hệ thống", + "compressionMinLength": "Độ dài tin nhắn tối thiểu", + "compressionSkipRules": "Bỏ qua các quy tắc nén", + "compressionSkipRulesDesc": "Nhấp vào các quy tắc để bỏ qua chúng trong quá trình nén", + "compressionPreservePatterns": "Giữ lại các mẫu", + "compressionPreservePatternsDesc": "Các mẫu regex không bao giờ bị nén (mỗi mẫu một dòng)", + "compressionLogTitle": "Nhật ký nén", + "compressionLogEmpty": "Chưa có yêu cầu nào được nén. Thống kê nén sẽ xuất hiện ở đây khi các yêu cầu được xử lý với tính năng nén được bật.", "minutes": "phút", "compressionModeRtk": "RTK", - "compressionModeRtkDesc": "Command-aware tool output filtering", - "compressionModeStacked": "Stacked", - "compressionModeStackedDesc": "RTK tool-output filtering followed by Caveman message compression", - "qdrantTitle": "Qdrant (Vector memory)", - "qdrantDesc": "Optional. Indexes semantic memories in an external vector database for faster retrieval.", - "qdrantStatusActive": "Active", - "qdrantStatusError": "Error", - "qdrantStatusDisabled": "Disabled", - "qdrantEnable": "Enable Qdrant", - "qdrantEnableDesc": "When enabled, semantic/hybrid strategy can use Qdrant to retrieve memories.", - "qdrantTesting": "Testing...", - "qdrantTestConnection": "Test connection", - "qdrantSaved": "Configuration saved", - "qdrantSaveError": "Failed to save configuration", - "qdrantHostHint": "Without port. Example: 127.0.0.1 or http://qdrant", - "qdrantPort": "Port", - "qdrantPortHint": "Qdrant default: 6333", - "qdrantCollectionHint": "Where memory points will be stored.", - "qdrantEmbeddingModel": "Embedding model", - "qdrantHelpTitle": "Quick setup help", - "qdrantHelpQuickTitle": "Quick setup (Qdrant + OpenRouter)", - "qdrantHelpStep1": "1. Host: Qdrant IP/URL, Port: 6333, Collection: omniroute_memory.", - "qdrantHelpStep2": "2. If using nvidia/llama-nemotron-embed-vl-1b-v2:free, use collection dimension 2048.", - "qdrantHelpStep3": "3. Model field: openrouter/nvidia/llama-nemotron-embed-vl-1b-v2:free.", - "qdrantHelpStep4": "4. Save, test connection, then test search.", - "qdrantEmbeddingQuickSelect": "Quick select from discovered models...", + "compressionModeRtkDesc": "Bộ lọc đầu ra công cụ nhận biết lệnh", + "compressionModeStacked": "Xếp chồng", + "compressionModeStackedDesc": "Lọc đầu ra công cụ RTK, sau đó nén tin nhắn bằng Caveman", + "qdrantTitle": "Qdrant (Bộ nhớ vectơ)", + "qdrantDesc": "Tùy chọn. Lập chỉ mục các mục bộ nhớ ngữ nghĩa trong một cơ sở dữ liệu vectơ bên ngoài để truy xuất nhanh hơn.", + "qdrantStatusActive": "Đang hoạt động", + "qdrantStatusError": "Lỗi", + "qdrantStatusDisabled": "Đã tắt", + "qdrantEnable": "Bật Qdrant", + "qdrantEnableDesc": "Khi được bật, chiến lược ngữ nghĩa/hỗn hợp có thể sử dụng Qdrant để truy xuất các mục bộ nhớ.", + "qdrantTesting": "Đang kiểm tra...", + "qdrantTestConnection": "Kiểm tra kết nối", + "qdrantSaved": "Đã lưu cấu hình", + "qdrantSaveError": "Lưu cấu hình thất bại", + "qdrantHostHint": "Không kèm cổng. Ví dụ: 127.0.0.1 hoặc http://qdrant", + "qdrantPort": "Cổng", + "qdrantPortHint": "Mặc định của Qdrant: 6333", + "qdrantCollectionHint": "Nơi các điểm bộ nhớ sẽ được lưu trữ.", + "qdrantEmbeddingModel": "Mô hình embedding", + "qdrantHelpTitle": "Trợ giúp thiết lập nhanh", + "qdrantHelpQuickTitle": "Thiết lập nhanh (Qdrant + OpenRouter)", + "qdrantHelpStep1": "1. Máy chủ: IP/URL của Qdrant, Cổng: 6333, Bộ sưu tập: omniroute_memory.", + "qdrantHelpStep2": "2. Nếu sử dụng nvidia/llama-nemotron-embed-vl-1b-v2:free, hãy đặt số chiều của bộ sưu tập là 2048.", + "qdrantHelpStep3": "3. Trường mô hình: openrouter/nvidia/llama-nemotron-embed-vl-1b-v2:free.", + "qdrantHelpStep4": "4. Lưu, kiểm tra kết nối, sau đó kiểm tra tìm kiếm.", + "qdrantEmbeddingQuickSelect": "Chọn nhanh từ các mô hình được phát hiện...", "qdrantEmbeddingInputPlaceholder": "openai/text-embedding-3-small", - "qdrantEmbeddingHint": "Format: provider/model. The provider credential must be configured.", - "qdrantApiKeyPlaceholderKeep": "(leave empty to keep current key)", - "qdrantApiKeyPlaceholderOptional": "(leave empty if not used)", - "qdrantSaveHint": "Tip: edit host/port/collection/model and click Save. API key is optional.", - "qdrantSearchTestTitle": "Search test", - "qdrantSearchTestDesc": "Generates embedding and searches in Qdrant.", - "qdrantSearchPlaceholder": "Example: user preferences, history, etc", - "qdrantNoResults": "No results (or Qdrant is not configured).", - "qdrantCleanupTitle": "Retention and cleanup", - "qdrantCleanupDesc": "Removes expired and old points based on", - "searching": "Searching...", - "cleaning": "Cleaning...", - "cleanNow": "Clean now", + "qdrantEmbeddingHint": "Định dạng: nhà cung cấp/mô hình. Thông tin xác thực của nhà cung cấp phải được cấu hình.", + "qdrantApiKeyPlaceholderKeep": "(để trống để giữ khóa hiện tại)", + "qdrantApiKeyPlaceholderOptional": "(để trống nếu không sử dụng)", + "qdrantSaveHint": "Mẹo: chỉnh sửa máy chủ/cổng/bộ sưu tập/mô hình rồi nhấn Lưu. API key là tùy chọn.", + "qdrantSearchTestTitle": "Kiểm tra tìm kiếm", + "qdrantSearchTestDesc": "Tạo embedding và tìm kiếm trong Qdrant.", + "qdrantSearchPlaceholder": "Ví dụ: tùy chọn của người dùng, lịch sử, v.v.", + "qdrantNoResults": "Không có kết quả (hoặc Qdrant chưa được cấu hình).", + "qdrantCleanupTitle": "Lưu giữ và dọn dẹp", + "qdrantCleanupDesc": "Xóa các điểm đã hết hạn và cũ dựa trên", + "searching": "Đang tìm kiếm...", + "cleaning": "Đang dọn dẹp...", + "cleanNow": "Dọn dẹp ngay", "optional": "Tùy chọn", - "current": "hiện tại", + "current": "Hiện tại", "remove": "Xóa", "search": "Tìm kiếm", "oneproxyTitle": "Thị trường proxy miễn phí 1proxy", "oneproxyTotalProxies": "Tổng số proxy", "oneproxyAvgQuality": "Chất lượng trung bình", - "resilienceScope": "Phạm vi:", - "resilienceTrigger": "Trình kích hoạt:", - "resilienceEffect": "Hiệu ứng:", - "resilienceRequestQueueTitle": "Request Queue & Rate", - "resilienceAutoEnableApiKeyProviders": "Auto-enable for API-key providers", - "resilienceRequestsPerMinute": "Requests per minute", - "resilienceMinTimeBetweenRequests": "Minimum time between requests", - "resilienceConcurrentRequests": "Concurrent requests", - "resilienceMaxQueueWaitTime": "Thời gian chờ xếp hàng tối đa", - "resilienceBaseCooldown": "Base cooldown", - "resilienceUseUpstreamRetryHints": "Use upstream retry hints", - "resilienceDefaultPerProvider": "Default (per provider)", - "resilienceAlwaysOn": "Always on", - "resilienceAlwaysOff": "Always off", + "resilienceScope": "Phạm vi áp dụng:", + "resilienceTrigger": "Điều kiện kích hoạt:", + "resilienceEffect": "Tác động:", + "resilienceRequestQueueTitle": "Hàng đợi yêu cầu và tốc độ", + "resilienceAutoEnableApiKeyProviders": "Tự động bật cho các nhà cung cấp sử dụng API key", + "resilienceRequestsPerMinute": "Số yêu cầu mỗi phút", + "resilienceMinTimeBetweenRequests": "Thời gian tối thiểu giữa các yêu cầu", + "resilienceConcurrentRequests": "Số yêu cầu đồng thời", + "resilienceMaxQueueWaitTime": "Thời gian chờ hàng đợi tối đa", + "resilienceBaseCooldown": "Thời gian giãn cách cơ bản", + "resilienceUseUpstreamRetryHints": "Sử dụng gợi ý thử lại từ máy chủ thượng nguồn", + "resilienceDefaultPerProvider": "Mặc định (theo nhà cung cấp)", + "resilienceAlwaysOn": "Luôn bật", + "resilienceAlwaysOff": "Luôn tắt", "routingRemoveEntry": "Xóa mục nhập", - "routingNeedlesSubstrings": "Kim (chuỗi con để phù hợp)", + "routingNeedlesSubstrings": "Chuỗi cần khớp (chuỗi con cần khớp)", "routingCaseSensitive": "Phân biệt chữ hoa chữ thường", "routingPrefixes": "Tiền tố", - "routingMatch": "Trận đấu", - "routingReplacement": "thay thế", + "routingMatch": "Khớp", + "routingReplacement": "Thay thế", "routingReplaceAllOccurrences": "Thay thế tất cả các lần xuất hiện", "routingPatternRegex": "Mẫu (regex)", "routingFlags": "Cờ", - "routingNeedles": "kim tiêm", + "routingNeedles": "Chuỗi cần khớp", "routingBlockText": "Chặn văn bản", - "routingIdempotencyKey": "Chìa khóa bình đẳng", + "routingIdempotencyKey": "Khóa chống trùng lặp", "routingEntrypoint": "Điểm vào", "routingVersionFormat": "Định dạng phiên bản", "routingCchAlgorithm": "Thuật toán CCH", - "routingWordsToObfuscate": "Các từ cần làm xáo trộn (ZWJ được chèn sau ký tự đầu tiên)", + "routingWordsToObfuscate": "Các từ cần làm rối (chèn ZWJ sau ký tự đầu tiên)", "logsSettingsTitle": "Cài đặt nhật ký", - "detailedLogsLabel": "Đã bật nhật ký chi tiết", + "detailedLogsLabel": "Bật nhật ký chi tiết", "detailedLogsDesc": "Bật ghi nhật ký yêu cầu/phản hồi chi tiết", - "callLogPipelineLabel": "Đường dẫn nhật ký cuộc gọi", + "callLogPipelineLabel": "Quy trình xử lý nhật ký cuộc gọi", "callLogPipelineDesc": "Bật quy trình xử lý nhật ký cuộc gọi", "maxDetailSizeLabel": "Kích thước chi tiết tối đa (KB)", "maxDetailSizeDesc": "Kích thước tối đa cho các mục nhật ký chi tiết", "ringBufferSizeLabel": "Kích thước bộ đệm vòng", - "ringBufferSizeDesc": "Kích thước của vòng đệm cho nhật ký", - "semanticCacheEnabledLabel": "Đã bật bộ nhớ đệm ngữ nghĩa", - "semanticCacheMaxSizeLabel": "Kích thước tối đa của bộ đệm ngữ nghĩa", - "semanticCacheMaxSizeDesc": "Số mục nhập bộ nhớ đệm ngữ nghĩa tối đa", - "semanticCacheTTLLabel": "Bộ nhớ đệm ngữ nghĩa TTL", - "promptCacheEnabledLabel": "Đã bật bộ đệm nhắc nhở", - "promptCacheEnabledDesc": "Bật bộ nhớ đệm nhanh chóng", - "promptCacheStrategyLabel": "Chiến lược bộ nhớ đệm nhanh chóng", - "promptCacheStrategyDesc": "Chiến lược lưu vào bộ nhớ đệm nhanh chóng", - "alwaysPreserveClientCacheLabel": "Luôn bảo toàn bộ đệm của máy khách", - "alwaysPreserveClientCacheDesc": "Chính sách bảo quản bộ đệm của máy khách", + "ringBufferSizeDesc": "Kích thước của bộ đệm vòng cho nhật ký", + "semanticCacheEnabledLabel": "Bật cache ngữ nghĩa", + "semanticCacheMaxSizeLabel": "Kích thước tối đa của cache ngữ nghĩa", + "semanticCacheMaxSizeDesc": "Số lượng mục nhập cache ngữ nghĩa tối đa", + "semanticCacheTTLLabel": "TTL của cache ngữ nghĩa", + "promptCacheEnabledLabel": "Bật prompt cache", + "promptCacheEnabledDesc": "Bật lưu prompt vào cache", + "promptCacheStrategyLabel": "Chiến lược prompt cache", + "promptCacheStrategyDesc": "Chiến lược lưu prompt vào cache", + "alwaysPreserveClientCacheLabel": "Luôn bảo toàn cache của client", + "alwaysPreserveClientCacheDesc": "Chính sách bảo toàn cache của client", "logRetentionPolicyTitle": "Chính sách lưu giữ nhật ký", - "resilienceUseUpstream429HintsForBreaker": "Sử dụng gợi ý ngược dòng 429 (ngắt)", - "appearanceLogoPreviewAlt": "Xem trước biểu trưng", - "appearanceFaviconPreviewAlt": "Xem trước biểu tượng yêu thích", + "resilienceUseUpstream429HintsForBreaker": "Sử dụng gợi ý 429 từ upstream (breaker)", + "appearanceLogoPreviewAlt": "Bản xem trước logo", + "appearanceFaviconPreviewAlt": "Bản xem trước favicon", "oneproxyLastSync": "Đồng bộ hóa lần cuối", "oneproxyAllProtocols": "Tất cả các giao thức", - "oneproxyCountryCodePlaceholder": "Mã quốc gia (ví dụ: Hoa Kỳ)", + "oneproxyCountryCodePlaceholder": "Mã quốc gia (ví dụ: US)", "oneproxyMinQualityPlaceholder": "Chất lượng tối thiểu", "oneproxyLoadingProxies": "Đang tải proxy...", "oneproxyLastSyncLabel": "Đồng bộ hóa lần cuối:", - "oneproxyProxiesFetched": "Proxy được tìm nạp:", + "oneproxyProxiesFetched": "Số proxy đã tải về:", "oneproxyConsecutiveFailures": "Thất bại liên tiếp:", "oneproxyErrorLabel": "Lỗi:", - "oneproxyNever": "không bao giờ", + "oneproxyNever": "Không bao giờ", "oneproxySyncStatusTitle": "Trạng thái đồng bộ hóa", - "oneproxySuccess": "thành công", - "oneproxyFailed": "thất bại", - "routingAntigravitySignatureTitle": "Chế độ bộ nhớ đệm chữ ký phản trọng lực", - "routingAntigravitySignatureDesc": "__MISSING__:Control whether OmniRoute reuses only stored Gemini thought signatures or accepts validated client-provided signatures in Antigravity-compatible tool-call flows.", - "routingAntigravitySignatureEnabledLabel": "__MISSING__:Enabled", - "routingAntigravitySignatureEnabledDesc": "__MISSING__:Current behavior. Ignore client-provided signatures and keep using the stored OmniRoute flow.", - "routingAntigravitySignatureBypassLabel": "__MISSING__:Bypass", - "routingAntigravitySignatureBypassDesc": "__MISSING__:Accept client-provided signatures after lightweight validation and fall back to the stored signature when invalid.", - "routingAntigravitySignatureBypassStrictLabel": "__MISSING__:Bypass Strict", - "routingAntigravitySignatureBypassStrictDesc": "__MISSING__:Require full protobuf validation before accepting a client-provided signature.", - "routingHeaderFingerprintTitle": "Dấu vân tay tiêu đề (mỗi nhà cung cấp)", + "oneproxySuccess": "Thành công", + "oneproxyFailed": "Thất bại", + "routingAntigravitySignatureTitle": "Chế độ cache chữ ký Antigravity", + "routingAntigravitySignatureDesc": "Kiểm soát việc OmniRoute chỉ tái sử dụng các chữ ký tư duy Gemini đã lưu trữ hay chấp nhận các chữ ký do máy khách cung cấp đã được xác thực trong các luồng gọi công cụ tương thích với Antigravity.", + "routingAntigravitySignatureEnabledLabel": "Đã bật", + "routingAntigravitySignatureEnabledDesc": "Hành vi hiện tại. Bỏ qua các chữ ký do máy khách cung cấp và tiếp tục sử dụng luồng OmniRoute đã lưu trữ.", + "routingAntigravitySignatureBypassLabel": "Bỏ qua", + "routingAntigravitySignatureBypassDesc": "Chấp nhận các chữ ký do máy khách cung cấp sau khi xác thực nhẹ và dùng chữ ký đã lưu làm phương án dự phòng khi không hợp lệ.", + "routingAntigravitySignatureBypassStrictLabel": "Bỏ qua nghiêm ngặt", + "routingAntigravitySignatureBypassStrictDesc": "Yêu cầu xác thực protobuf đầy đủ trước khi chấp nhận chữ ký do máy khách cung cấp.", + "routingHeaderFingerprintTitle": "Dấu vân tay header (mỗi nhà cung cấp)", "routingServerRejectedSave": "⚠ Máy chủ từ chối lưu:", - "routingAddTransformOp": "Thêm một op biến đổi", - "routingClientCacheControlTitle": "Kiểm soát bộ nhớ đệm của máy khách", - "routingClientCacheControlDesc": "__MISSING__:Configure whether OmniRoute preserves client-provided cache_control markers", - "routingClientCacheControlAutoDesc": "__MISSING__:For deterministic Claude-compatible flows, preserve client-provided cache_control as-is. If the request has no cache_control, OmniRoute does not inject any bridge-owned markers for CC-compatible third-party proxy compatibility.", - "routingClientCacheControlAlwaysLabel": "__MISSING__:Always Preserve", - "routingClientCacheControlAlwaysDesc": "__MISSING__:Always forward client-provided cache_control headers to upstream providers as-is.", - "routingClientCacheControlNeverLabel": "__MISSING__:Never Preserve", - "routingClientCacheControlNeverDesc": "__MISSING__:Always remove client cache_control headers and let OmniRoute manage caching where native provider flows support it.", - "routingZeroConfigTitle": "Tự động định tuyến không cấu hình", - "routingZeroConfigDesc": "__MISSING__:Enable automatic provider selection using the auto/ prefix. When enabled, requests to auto, auto/coding, auto/fast, etc. will dynamically route across all connected providers.", + "routingAddTransformOp": "Thêm một thao tác biến đổi", + "routingClientCacheControlTitle": "Kiểm soát cache của máy khách", + "routingClientCacheControlDesc": "Cấu hình xem OmniRoute có giữ lại các đánh dấu cache_control do máy khách cung cấp hay không", + "routingClientCacheControlAutoDesc": "Đối với các luồng tương thích với Claude mang tính xác định, giữ nguyên cache_control do máy khách cung cấp. Nếu yêu cầu không có cache_control, OmniRoute sẽ không chèn bất kỳ dấu đánh dấu nào do cầu nối quản lý để tương thích với các proxy bên thứ ba hỗ trợ CC.", + "routingClientCacheControlAlwaysLabel": "Luôn giữ lại", + "routingClientCacheControlAlwaysDesc": "Luôn chuyển tiếp các header cache_control do máy khách cung cấp đến các nhà cung cấp upstream dưới dạng nguyên bản.", + "routingClientCacheControlNeverLabel": "Không bao giờ giữ lại", + "routingClientCacheControlNeverDesc": "Luôn xóa các header cache_control của máy khách và để OmniRoute quản lý việc lưu cache tại những nơi luồng nhà cung cấp gốc hỗ trợ.", + "routingZeroConfigTitle": "Tự động định tuyến không cần cấu hình", + "routingZeroConfigDesc": "Bật tính năng tự động chọn nhà cung cấp bằng tiền tố auto/. Khi được bật, các yêu cầu tới auto, auto/coding, auto/fast, v.v. sẽ được định tuyến linh hoạt giữa tất cả các nhà cung cấp đã kết nối.", "routingDefaultAutoVariant": "Biến thể tự động mặc định", - "visionBridge": "Cầu tầm nhìn", - "visionBridgeDesc": "__MISSING__:Run an automatic vision-to-text fallback before routing image requests to text-only models.", - "visionBridgeEnabledLabel": "__MISSING__:Enabled", - "visionBridgeEnabledDesc": "__MISSING__:Toggle the pre-call bridge that replaces image parts with extracted text.", - "visionBridgeModel": "Mô hình cầu", + "visionBridge": "Cầu nối thị giác", + "visionBridgeDesc": "Tự động chạy phương án dự phòng chuyển đổi hình ảnh sang văn bản trước khi định tuyến các yêu cầu hình ảnh đến các mô hình chỉ hỗ trợ văn bản.", + "visionBridgeEnabledLabel": "Đã bật", + "visionBridgeEnabledDesc": "Bật/tắt cầu nối trước cuộc gọi để thay thế các phần hình ảnh bằng văn bản được trích xuất.", + "visionBridgeModel": "Mô hình cầu nối", "visionBridgeModelPlaceholder": "openai/gpt-4o-mini", - "visionBridgeModelHint": "__MISSING__:Any OmniRoute model ID that supports vision can be used here.", - "visionBridgePrompt": "Nhắc nhở cầu", + "visionBridgeModelHint": "Có thể sử dụng bất kỳ ID mô hình OmniRoute nào hỗ trợ xử lý hình ảnh ở đây.", + "visionBridgePrompt": "Prompt cầu nối", "visionBridgePromptPlaceholder": "Hãy mô tả hình ảnh này một cách ngắn gọn.", - "visionBridgePromptHint": "__MISSING__:Sent to the vision model before the extracted description is injected back into the original request.", + "visionBridgePromptHint": "Được gửi đến mô hình thị giác trước khi phần mô tả được trích xuất được chèn lại vào yêu cầu gốc.", "visionBridgeTimeoutMs": "Thời gian chờ (ms)", - "visionBridgeMaxImagesPerRequest": "Hình ảnh tối đa cho mỗi yêu cầu", - "resilienceMaxBackoffSteps": "Max backoff steps", - "resilienceProviderBreakerTitle": "Circuit Breaker per Provider", - "resilienceFailureThreshold": "Failure threshold", - "resilienceDegradationThreshold": "Degradation threshold", - "resilienceResetTimeout": "Đặt lại thời gian chờ", + "visionBridgeMaxImagesPerRequest": "Số lượng hình ảnh tối đa cho mỗi yêu cầu", + "resilienceMaxBackoffSteps": "Số bước lùi tối đa", + "resilienceProviderBreakerTitle": "Bộ ngắt mạch cho mỗi nhà cung cấp", + "resilienceFailureThreshold": "Ngưỡng thất bại", + "resilienceDegradationThreshold": "Ngưỡng suy giảm hiệu năng", + "resilienceResetTimeout": "Thời gian chờ đặt lại", "resilienceFailureThresholdLabel": "Ngưỡng thất bại", - "resilienceResetTimeoutLabel": "Đặt lại thời gian chờ", - "resilienceConnectionCooldownTitle": "Connection Cooldown", - "resilienceUseUpstreamRetryHintsLabel": "Sử dụng gợi ý thử lại ngược dòng", - "resilienceUseUpstream429BreakerLabel": "Sử dụng gợi ý ngược dòng 429 (ngắt)", - "resilienceMaxBackoffStepsLabel": "Bước lùi tối đa", + "resilienceResetTimeoutLabel": "Thời gian chờ đặt lại", + "resilienceConnectionCooldownTitle": "Thời gian chờ trước khi kết nối lại", + "resilienceUseUpstreamRetryHintsLabel": "Sử dụng gợi ý thử lại từ máy chủ thượng nguồn", + "resilienceUseUpstream429BreakerLabel": "Sử dụng gợi ý 429 từ máy chủ thượng nguồn (bộ ngắt mạch)", + "resilienceMaxBackoffStepsLabel": "Số bước lùi tối đa", "resilienceYes": "Có", "resilienceNo": "Không", - "resilienceDefault": "Default", - "storageDatabaseBackupRetention": "Lưu giữ sao lưu cơ sở dữ liệu", - "storagePurgeData": "Xóa dữ liệu", + "resilienceDefault": "Mặc định", + "storageDatabaseBackupRetention": "Thời gian lưu trữ bản sao lưu cơ sở dữ liệu", + "storagePurgeData": "Xóa sạch dữ liệu", "retentionQuotaSnapshots": "Ảnh chụp nhanh hạn ngạch (ngày)", "retentionMcpAudit": "Kiểm toán MCP (ngày)", "retentionA2aEvents": "Sự kiện A2A (ngày)", "retentionCallLogs": "Nhật ký cuộc gọi (ngày)", "retentionUsageHistory": "Lịch sử sử dụng (ngày)", "retentionMemoryEntries": "Mục nhập bộ nhớ (ngày)", - "storageAutoVacuumMode": "Chế độ hút bụi tự động", - "storageScheduledVacuum": "chân không theo lịch trình", - "storageVacuumHour": "Giờ chân không (0-23)", + "storageAutoVacuumMode": "Chế độ dọn dẹp tự động", + "storageScheduledVacuum": "Dọn dẹp theo lịch", + "storageVacuumHour": "Giờ dọn dẹp (0-23)", "storagePageSize": "Kích thước trang (byte)", "storageDatabaseSize": "Kích thước cơ sở dữ liệu", - "storagePageCount": "Số trang", - "storageFreelistCount": "Số lượng danh sách tự do", - "storageLastVacuum": "Chân không cuối cùng", - "storageLastOptimization": "Tối ưu hóa lần cuối", + "storagePageCount": "Số lượng trang", + "storageFreelistCount": "Số trang trống", + "storageLastVacuum": "Lần dọn dẹp (Vacuum) cuối cùng", + "storageLastOptimization": "Lần tối ưu hóa cuối cùng", "storageIntegrityCheck": "Kiểm tra tính toàn vẹn", - "storageIntegrityOk": "✓ Được rồi", + "storageIntegrityOk": "✓ OK", "storageIntegrityError": "✗ Lỗi", - "storageUsageTokenBuffer": "Bộ đệm mã thông báo sử dụng", + "storageUsageTokenBuffer": "Bộ đệm token cho mức sử dụng", "compressionSettingsAutoTriggerMode": "Chế độ kích hoạt tự động", "compressionSettingsMcpDescriptionCompression": "Nén mô tả MCP", - "compressionSettingsCavemanIntensity": "Cường độ thượng cổ", + "compressionSettingsCavemanIntensity": "Cường độ Caveman", "compressionSettingsCavemanOutputMode": "Chế độ đầu ra Caveman", "compressionSettingsOutputIntensity": "Cường độ đầu ra", - "compressionSettingsAutoClarityBypass": "Tự động bỏ qua rõ ràng", - "resilienceWaitForCooldown": "Chờ thời gian hồi chiêu", + "compressionSettingsAutoClarityBypass": "Bỏ qua tính năng tự động làm rõ", + "resilienceWaitForCooldown": "Chờ thời gian hồi", "resilienceEnableServerSideWait": "Bật tính năng chờ phía máy chủ", "resilienceMaximumRetries": "Số lần thử lại tối đa", "resilienceMaximumWaitPerRetry": "Thời gian chờ tối đa cho mỗi lần thử lại", - "memorySkillsSkillsmpMarketplace": "Thị trường SkillMP", - "memorySkillsFailedToSave": "Không lưu được", + "memorySkillsSkillsmpMarketplace": "Thị trường SkillsMP", + "memorySkillsFailedToSave": "Không thể lưu", "memorySkillsApiKey": "Khóa API", - "memorySkillsActiveSkillsProvider": "Nhà cung cấp kỹ năng tích cực", + "memorySkillsActiveSkillsProvider": "Nhà cung cấp kỹ năng đang hoạt động", "cliproxyapiFallback": "Dự phòng CLIProxyAPI", "cliproxyapiEnableFallback": "Bật dự phòng CLIProxyAPI", "cliproxyapiUrl": "URL CLIProxyAPI", "cliproxyapiStatus": "Trạng thái CLIProxyAPI", - "cliproxyapiNotDetected": "Không được phát hiện", - "payloadRulesTitle": "Quy tắc tải trọng", - "payloadRulesDesc": "__MISSING__:Configure request payload mutations by model and protocol. Changes are persisted in settings and hot reloaded into the runtime immediately after save.", - "payloadRuleDefaultTitle": "__MISSING__:default", - "payloadRuleDefaultDesc": "__MISSING__:Applies params only when the target path is missing from the outgoing payload.", - "payloadRuleOverrideTitle": "__MISSING__:override", - "payloadRuleOverrideDesc": "__MISSING__:Forces values onto the payload, replacing anything already present at that path.", - "payloadRuleFilterTitle": "__MISSING__:filter", - "payloadRuleFilterDesc": "__MISSING__:Removes blocked params from the payload before the upstream request is sent.", - "payloadRuleDefaultRawTitle": "__MISSING__:defaultRaw", - "payloadRuleDefaultRawDesc": "__MISSING__:Like default, but string values are parsed as JSON first when possible. The legacy input alias default-raw is also accepted on save.", - "payloadEditorTitle": "__MISSING__:Editor", - "payloadEditorDesc": "__MISSING__:Use the runtime schema shape: default, override, filter, defaultRaw. The API also accepts the legacy input key default-raw.", - "payloadEditorReady": "__MISSING__:Ready", - "payloadResetInfo": "__MISSING__:Editor reset to the neutral template. Save to apply it.", - "payloadSaveSuccess": "__MISSING__:Payload rules saved and hot reloaded.", - "payloadJsonParseError": "__MISSING__:JSON parse error: {error}", - "payloadMustBeObject": "__MISSING__:Payload rules must be a JSON object.", - "payloadInvalidJson": "__MISSING__:Invalid JSON payload.", - "payloadValidJsonRequired": "__MISSING__:Payload rules must be valid JSON before saving.", - "savePayloadRules": "__MISSING__:Save Payload Rules", - "requestLimitsTitle": "__MISSING__:Request Limits", - "requestLimitsDesc": "__MISSING__:Configure global request limits and concurrency guards.", - "maxRequestSizeLabel": "__MISSING__:Max Request Size (MB)", - "maxRequestSizeDesc": "__MISSING__:Maximum allowed size for incoming API requests.", - "maxResponseSizeLabel": "__MISSING__:Max Response Size (MB)", - "maxResponseSizeDesc": "__MISSING__:Maximum allowed size for outgoing API responses.", - "maxRequestTokensLabel": "__MISSING__:Max Request Tokens", - "maxRequestTokensDesc": "__MISSING__:Maximum total tokens allowed in a single request.", - "maxResponseTokensLabel": "__MISSING__:Max Response Tokens", - "maxResponseTokensDesc": "__MISSING__:Maximum total tokens allowed in a single response.", - "modelCooldownsTitle": "Các mẫu đang trong thời gian hồi chiêu", - "modelCooldownsEmpty": "Hiện tại không có mẫu nào đang trong thời gian hồi chiêu.", - "codexFastTierTitle": "Cấp độ nhanh của Codex", - "codexFastTierDesc": "Đưa vào toàn cầu service_tier=priority cho các yêu cầu OpenAI Codex.", - "codexFastTierHint": "Khi được bật, OmniRoute sẽ thêm service_tier=priority vào các yêu cầu Codex gửi đi cho các kết nối chưa chỉ định cấp. Bậc ưu tiên yêu cầu khóa API OpenAI Enterprise hoặc đường dẫn Codex ChatGPT-auth; các loại khóa khác sẽ nhận được lỗi liên quan đến cấp độ từ OpenAI. Cài đặt cho mỗi kết nối trên trang nhà cung cấp Codex được ưu tiên.", - "codexFastTierSaveError": "Không thể cập nhật cài đặt Cấp nhanh Codex", - "codexFastTierTierLabel": "__MISSING__:Service tier", - "codexFastTierTierPriority": "__MISSING__:Priority", - "codexFastTierTierFlex": "__MISSING__:Flex", - "codexFastTierTierDefault": "__MISSING__:Default", - "codexFastTierModelsLabel": "__MISSING__:Fast-tier models", - "codexFastTierModelsHint": "__MISSING__:Only checked models receive service_tier when Fast Tier is enabled.", - "codexFastTierModelCheckbox": "__MISSING__:Enable Fast Tier for {model}", - "claudeFastModeTitle": "Chế độ nhanh Claude", - "claudeFastModeDesc": "Chọn các yêu cầu Claude đã chọn vào Chế độ nhanh nhân loại (tốc độ: \"nhanh\").", - "claudeFastModeHint": "Anthropic không chính thức hỗ trợ Chế độ nhanh cho các máy khách kiểu SDK. Khi được bật, OmniRoute sẽ chuyển tiếp tiêu đề X-CPA-Force-Fast-Mode để bản dựng CLIProxyAPI được ghép nối có thể chọn tham gia giả mạo điểm nhập. Chỉ các mẫu Opus được liệt kê mới được kiểm soát bởi quá trình kiểm tra phía khách hàng của Anthropic. Cấp đăng ký, gói tối đa và số dư tín dụng Chế độ nhanh vẫn được thực thi ở phía máy chủ - Anthropic có thể trả về out_of_credits ngay cả khi bật nút chuyển đổi.", + "cliproxyapiNotDetected": "Không phát hiện thấy", + "payloadRulesTitle": "Quy tắc payload", + "payloadRulesDesc": "Cấu hình việc biến đổi payload yêu cầu theo mô hình và giao thức. Các thay đổi được lưu trong cài đặt và được tải lại nóng vào môi trường chạy ngay sau khi lưu.", + "payloadRuleDefaultTitle": "default", + "payloadRuleDefaultDesc": "Chỉ áp dụng các tham số khi đường dẫn đích bị thiếu trong payload gửi đi.", + "payloadRuleOverrideTitle": "override", + "payloadRuleOverrideDesc": "Buộc ghi đè các giá trị vào payload, thay thế mọi giá trị đã có tại đường dẫn đó.", + "payloadRuleFilterTitle": "filter", + "payloadRuleFilterDesc": "Loại bỏ các tham số bị chặn khỏi payload trước khi gửi yêu cầu đến máy chủ thượng nguồn.", + "payloadRuleDefaultRawTitle": "defaultRaw", + "payloadRuleDefaultRawDesc": "Giống như default, nhưng các giá trị chuỗi sẽ được phân tích cú pháp thành JSON trước nếu có thể. Bí danh nhập cũ default-raw cũng được chấp nhận khi lưu.", + "payloadEditorTitle": "Trình chỉnh sửa", + "payloadEditorDesc": "Sử dụng cấu trúc lược đồ của môi trường chạy: default, override, filter, defaultRaw. API cũng chấp nhận khóa đầu vào cũ default-raw.", + "payloadEditorReady": "Sẵn sàng", + "payloadResetInfo": "Trình chỉnh sửa đã được đặt lại về mẫu trung lập. Hãy lưu để áp dụng.", + "payloadSaveSuccess": "Đã lưu các quy tắc payload và tải lại nóng.", + "payloadJsonParseError": "Lỗi phân tích cú pháp JSON: {error}", + "payloadMustBeObject": "Quy tắc payload phải là một đối tượng JSON.", + "payloadInvalidJson": "Payload JSON không hợp lệ.", + "payloadValidJsonRequired": "Quy tắc payload phải là JSON hợp lệ trước khi lưu.", + "savePayloadRules": "Lưu quy tắc payload", + "requestLimitsTitle": "Giới hạn yêu cầu", + "requestLimitsDesc": "Cấu hình giới hạn yêu cầu toàn cục và các cơ chế kiểm soát đồng thời.", + "maxRequestSizeLabel": "Kích thước yêu cầu tối đa (MB)", + "maxRequestSizeDesc": "Kích thước tối đa được phép đối với các yêu cầu API gửi đến.", + "maxResponseSizeLabel": "Kích thước phản hồi tối đa (MB)", + "maxResponseSizeDesc": "Kích thước tối đa được phép đối với các phản hồi API gửi đi.", + "maxRequestTokensLabel": "Số token tối đa cho mỗi yêu cầu", + "maxRequestTokensDesc": "Tổng số token tối đa được phép trong một yêu cầu đơn lẻ.", + "maxResponseTokensLabel": "Số token tối đa cho mỗi phản hồi", + "maxResponseTokensDesc": "Tổng số token tối đa được phép trong một phản hồi đơn lẻ.", + "modelCooldownsTitle": "Các mô hình đang trong thời gian chờ", + "modelCooldownsEmpty": "Hiện không có mô hình nào đang trong thời gian chờ.", + "codexFastTierTitle": "Codex Fast Tier", + "codexFastTierDesc": "Thêm service_tier=priority trên toàn cục cho các yêu cầu OpenAI Codex.", + "codexFastTierHint": "Khi được bật, OmniRoute sẽ thêm service_tier=priority vào các yêu cầu Codex gửi đi của những kết nối chưa chỉ định cấp dịch vụ. Cấp Priority yêu cầu khóa API OpenAI Enterprise hoặc đường dẫn Codex xác thực bằng ChatGPT; các loại khóa khác sẽ nhận được lỗi liên quan đến cấp từ OpenAI. Cài đặt riêng cho từng kết nối trên trang nhà cung cấp Codex được ưu tiên.", + "codexFastTierSaveError": "Không thể cập nhật cài đặt Codex Fast Tier", + "codexFastTierTierLabel": "Cấp dịch vụ", + "codexFastTierTierPriority": "Ưu tiên (Priority)", + "codexFastTierTierFlex": "Linh hoạt (Flex)", + "codexFastTierTierDefault": "Mặc định", + "codexFastTierModelsLabel": "Các mô hình cấp nhanh (Fast-tier)", + "codexFastTierModelsHint": "Chỉ các mô hình được chọn mới nhận service_tier khi Fast Tier được bật.", + "codexFastTierModelCheckbox": "Bật Fast Tier cho {model}", + "claudeFastModeTitle": "Claude Fast Mode", + "claudeFastModeDesc": "Cho phép các yêu cầu Claude đã chọn sử dụng Anthropic Fast Mode (speed:\"fast\").", + "claudeFastModeHint": "Anthropic không chính thức hỗ trợ Fast Mode cho các ứng dụng khách kiểu SDK. Khi được bật, OmniRoute sẽ chuyển tiếp header X-CPA-Force-Fast-Mode để một bản dựng CLIProxyAPI được ghép nối có thể đăng ký bằng cách giả mạo điểm vào. Chỉ các mô hình Opus được liệt kê mới bị giới hạn bởi bước kiểm tra phía ứng dụng khách của Anthropic. Cấp gói đăng ký, gói Max và số dư tín dụng Fast Mode vẫn được thực thi ở phía máy chủ — Anthropic có thể trả về lỗi out_of_credits ngay cả khi tùy chọn này đang bật.", "claudeFastModeModelsLabel": "Áp dụng cho các mô hình ({count})", - "claudeFastModeModelCheckbox": "Bật Chế độ nhanh cho {model}", - "claudeFastModeSaveError": "Không thể cập nhật cài đặt Chế độ nhanh của Claude", + "claudeFastModeModelCheckbox": "Bật Fast Mode cho {model}", + "claudeFastModeSaveError": "Không thể cập nhật cài đặt Claude Fast Mode", "authz": { - "title": "__MISSING__:Authorization Inventory", - "description": "__MISSING__:5-tier route classification with live bypass policy. Read shows the full taxonomy; mutations re-prompt for the management password.", - "loading": "__MISSING__:Loading inventory…", - "loadError": "__MISSING__:Failed to load authz inventory", + "title": "Danh mục ủy quyền", + "description": "Phân loại định tuyến theo 5 cấp với chính sách bỏ qua đang áp dụng. Chế độ đọc hiển thị toàn bộ hệ thống phân loại; các thay đổi sẽ yêu cầu nhập lại mật khẩu quản lý.", + "loading": "Đang tải danh mục…", + "loadError": "Không thể tải danh mục ủy quyền (authz)", "tier": { - "LOCAL_ONLY": "__MISSING__:Local only", - "ALWAYS_PROTECTED": "__MISSING__:Always protected", - "MANAGEMENT": "__MISSING__:Management", - "CLIENT_API": "__MISSING__:Client API", - "PUBLIC": "__MISSING__:Public" + "LOCAL_ONLY": "Chỉ cục bộ", + "ALWAYS_PROTECTED": "Luôn được bảo vệ", + "MANAGEMENT": "Quản trị", + "CLIENT_API": "API ứng dụng khách", + "PUBLIC": "Công khai" }, "bypass": { - "section": "__MISSING__:Manage-scope bypass", + "section": "Bỏ qua phạm vi quản lý", "kill_switch": { - "label": "__MISSING__:Bypass kill-switch", - "desc": "__MISSING__:Master toggle. When off, no LOCAL_ONLY prefix is reachable from non-loopback regardless of the per-prefix list." + "label": "Công tắc vô hiệu hóa cơ chế bỏ qua", + "desc": "Công tắc chính. Khi tắt, không thể truy cập bất kỳ tiền tố LOCAL_ONLY nào từ địa chỉ không phải loopback, bất kể danh sách thiết lập cho từng tiền tố." }, "prefix": { - "label": "__MISSING__:Bypassable prefixes", - "desc": "__MISSING__:LOCAL_ONLY prefixes that manage-scope API keys (or dashboard sessions) may reach from non-loopback hosts.", - "add": "__MISSING__:Add prefix", - "placeholder": "__MISSING__:/api/mcp/v2/", - "empty": "__MISSING__:No prefixes configured. Bypass effectively off." + "label": "Các tiền tố có thể bỏ qua", + "desc": "Các tiền tố LOCAL_ONLY mà khóa API có phạm vi quản lý (hoặc phiên bảng điều khiển) có thể truy cập từ các máy chủ không phải loopback.", + "add": "Thêm tiền tố", + "placeholder": "/api/mcp/v2/", + "empty": "Chưa cấu hình tiền tố nào. Tính năng bỏ qua thực tế đang tắt." }, - "cli_tools_runtime_note": "__MISSING__:Spawn-capable prefix. Compile-time deny; cannot be made bypassable. Shown read-only." + "cli_tools_runtime_note": "Tiền tố có khả năng tạo tiến trình. Bị từ chối khi biên dịch; không thể thiết lập để bỏ qua. Hiển thị ở chế độ chỉ đọc." }, "password": { "prompt": { - "label": "__MISSING__:Current password", - "desc": "__MISSING__:Re-confirm to apply security-impacting changes." + "label": "Mật khẩu hiện tại", + "desc": "Xác nhận lại để áp dụng các thay đổi ảnh hưởng đến bảo mật." }, - "placeholder": "__MISSING__:Current management password", - "cancel": "__MISSING__:Cancel", - "submit": "__MISSING__:Apply" + "placeholder": "Mật khẩu quản lý hiện tại", + "cancel": "Hủy", + "submit": "Áp dụng" }, - "save": "__MISSING__:Save changes", - "saved": "__MISSING__:Authz settings updated", - "pending": "__MISSING__:Unsaved changes", + "save": "Lưu thay đổi", + "saved": "Đã cập nhật cài đặt phân quyền", + "pending": "Thay đổi chưa lưu", "badge": { - "bypassable": "__MISSING__:Bypassable via manage scope", - "strict": "__MISSING__:Strict loopback", - "auth_required": "__MISSING__:Auth required", - "public": "__MISSING__:Public", - "always_protected": "__MISSING__:Always protected", - "spawn_capable": "__MISSING__:Spawn-capable" + "bypassable": "Có thể bỏ qua bằng phạm vi quản lý", + "strict": "Chỉ cho phép kết nối loopback", + "auth_required": "Yêu cầu xác thực", + "public": "Công khai", + "always_protected": "Luôn được bảo vệ", + "spawn_capable": "Có khả năng tạo tiến trình" }, "error": { - "PASSWORD_REQUIRED": "__MISSING__:Current password required to apply these changes.", - "PASSWORD_MISMATCH": "__MISSING__:Current password is incorrect.", - "INSUFFICIENT_SCOPE": "__MISSING__:API key lacks the manage scope.", - "BYPASS_PREFIX_NOT_ALLOWED": "__MISSING__:One or more prefixes target spawn-capable routes and cannot be bypassed.", - "GENERIC": "__MISSING__:Failed to update authz settings." + "PASSWORD_REQUIRED": "Cần có mật khẩu hiện tại để áp dụng các thay đổi này.", + "PASSWORD_MISMATCH": "Mật khẩu hiện tại không chính xác.", + "INSUFFICIENT_SCOPE": "Khóa API không có phạm vi quản lý.", + "BYPASS_PREFIX_NOT_ALLOWED": "Một hoặc nhiều tiền tố nhắm đến các tuyến có khả năng tạo tiến trình và không thể bỏ qua.", + "GENERIC": "Không thể cập nhật cài đặt phân quyền." + }, + "cors": { + "wildcard": { + "title": "CORS is open to every origin (CORS_ALLOW_ALL=true)", + "desc": "Any website can call this server's API from a visitor's browser. Use only on trusted networks — set explicit origins in ALLOWED_ORIGINS and disable CORS_ALLOW_ALL in production." + } } }, - "resilienceBaseCooldownLabel": "Thời gian hồi chiêu cơ bản", + "resilienceBaseCooldownLabel": "Thời gian hồi cơ bản", "scopeLabel": "Phạm vi", - "triggerLabel": "Trình kích hoạt", - "effectLabel": "Hiệu ứng", + "triggerLabel": "Điều kiện kích hoạt", + "effectLabel": "Tác động", "statusEnabled": "Đã bật", "statusDisabled": "Đã tắt", - "resilienceRequestQueueScope": "Mỗi hàng đợi yêu cầu", - "resilienceRequestQueueTrigger": "Trước khi gửi lên thượng nguồn", - "resilienceRequestQueueEffect": "Xếp hàng đợi các yêu cầu, giới hạn sự đồng thời và loại bỏ các cuộc gọi", - "resilienceRequestQueueDesc": "Lớp này chỉ kiểm soát việc xếp hàng và tốc độ. Nó không lưu trữ thời gian hồi chiêu hoặc cầu dao mở.", - "resilienceAutoEnableApiKeyProvidersDesc": "Bật tính năng bảo vệ hàng đợi theo mặc định cho các kết nối khóa API đang hoạt động.", + "resilienceRequestQueueScope": "Theo từng hàng đợi yêu cầu", + "resilienceRequestQueueTrigger": "Trước khi gửi đến upstream", + "resilienceRequestQueueEffect": "Xếp hàng các yêu cầu, giới hạn số lượng yêu cầu đồng thời và giãn cách các cuộc gọi", + "resilienceRequestQueueDesc": "Lớp này chỉ kiểm soát việc xếp hàng và nhịp độ. Nó không lưu trữ thời gian hồi hoặc mở bộ ngắt mạch.", + "resilienceAutoEnableApiKeyProvidersDesc": "Bật tính năng bảo vệ hàng đợi theo mặc định cho các kết nối bằng khóa API đang hoạt động.", "resilienceMaxQueueWait": "Thời gian chờ xếp hàng tối đa", "resilienceConnectionCooldownScope": "Kết nối riêng lẻ", - "resilienceConnectionCooldownTrigger": "Khi một kết nối trả về lỗi ngược dòng tạm thời", - "resilienceConnectionCooldownEffect": "Tạm thời bỏ qua kết nối đó và tăng thời gian chờ cho các lỗi lặp lại", - "resilienceConnectionCooldownDesc": "Thời gian hồi chiêu cơ bản bao gồm các lỗi kết nối tạm thời. Khi bật gợi ý thử lại ngược dòng, cửa sổ rõ ràng của nhà cung cấp sẽ ghi đè thời gian hồi chiêu cục bộ.", - "resilienceUseUpstreamRetryHintsDesc": "Sử dụng các giá trị thử lại sau/đặt lại từ nhà cung cấp ngược tuyến khi có sẵn.", - "resilienceUseUpstream429BreakerHints": "Sử dụng gợi ý ngược dòng 429 để có thời gian hồi chiêu của bộ ngắt", - "resilienceUseUpstream429BreakerHintsShort": "Sử dụng gợi ý ngược dòng 429", - "resilienceUseUpstream429BreakerHintsDesc": "Áp dụng tín hiệu Thử lại sau/hết hạn ngạch từ 429 phản hồi cho thời gian hồi chiêu của bộ ngắt mạch. Mặc định sử dụng chính sách cho mỗi nhà cung cấp: bật trực tiếp nhà cung cấp đám mây; Các nhà cung cấp proxy ngược, tự lưu trữ và được CLI hỗ trợ mặc định tắt. Độc lập với \"Sử dụng gợi ý thử lại ngược dòng\".", + "resilienceConnectionCooldownTrigger": "Khi một kết nối trả về lỗi upstream tạm thời", + "resilienceConnectionCooldownEffect": "Tạm thời bỏ qua kết nối đó và tăng thời gian chờ tăng dần đối với các lỗi lặp lại.", + "resilienceConnectionCooldownDesc": "Thời gian hồi cơ bản áp dụng cho các lỗi kết nối tạm thời. Khi bật các gợi ý thử lại từ upstream, khoảng thời gian cụ thể của nhà cung cấp sẽ ghi đè thời gian hồi cục bộ.", + "resilienceUseUpstreamRetryHintsDesc": "Sử dụng các giá trị retry-after/reset từ nhà cung cấp upstream khi có sẵn.", + "resilienceUseUpstream429BreakerHints": "Sử dụng gợi ý 429 từ upstream cho thời gian hồi của bộ ngắt", + "resilienceUseUpstream429BreakerHintsShort": "Sử dụng gợi ý 429 từ upstream", + "resilienceUseUpstream429BreakerHintsDesc": "Áp dụng các tín hiệu Retry-After / hết hạn ngạch từ phản hồi 429 vào thời lượng hồi của bộ ngắt mạch. Mặc định sử dụng chính sách theo từng nhà cung cấp: các nhà cung cấp đám mây trực tiếp mặc định bật; các nhà cung cấp qua proxy ngược, tự lưu trữ và dựa trên CLI mặc định tắt. Độc lập với \"Sử dụng gợi ý thử lại từ upstream\".", "resilienceProviderBreakerScope": "Toàn bộ nhà cung cấp", - "resilienceProviderBreakerTrigger": "Lỗi vận chuyển/máy chủ cuối cùng sau khi hết kết nối dự phòng", + "resilienceProviderBreakerTrigger": "Các lỗi truyền tải/máy chủ cuối cùng sau khi đã dùng hết các phương án dự phòng kết nối", "resilienceProviderBreakerEffect": "Tạm thời chặn nhà cung cấp đó cho đến khi hết thời gian đặt lại", - "resilienceProviderBreakerDesc": "Trạng thái ngắt trực tiếp chỉ xuất hiện trên trang Sức khỏe. Giới hạn tốc độ 429 trong phạm vi kết nối vẫn ở trong Thời gian chờ kết nối và không ngắt bộ ngắt nhà cung cấp.", - "resilienceResetTime": "Đặt lại thời gian", - "resilienceWaitForCooldownTitle": "Chờ thời gian hồi chiêu", - "resilienceWaitForCooldownScope": "Yêu cầu hiện tại của khách hàng", - "resilienceWaitForCooldownTrigger": "Khi tất cả các kết nối ứng viên đã hạ nhiệt", - "resilienceWaitForCooldownEffect": "Chờ trên máy chủ và thử lại khi hết thời gian hồi chiêu đầu tiên", - "resilienceWaitForCooldownDesc": "Điều này chỉ ảnh hưởng đến yêu cầu hiện tại. Nó không lưu trữ kết nối hoặc trạng thái nhà cung cấp.", + "resilienceProviderBreakerDesc": "Trạng thái bộ ngắt mạch theo thời gian thực chỉ xuất hiện trên trang Sức khỏe. Các giới hạn tốc độ 429 theo kết nối vẫn ở trạng thái Thời gian chờ kết nối và không kích hoạt bộ ngắt mạch của nhà cung cấp.", + "resilienceResetTime": "Thời gian đặt lại", + "resilienceWaitForCooldownTitle": "Chờ hết thời gian chờ", + "resilienceWaitForCooldownScope": "Yêu cầu hiện tại của máy khách", + "resilienceWaitForCooldownTrigger": "Khi tất cả các kết nối ứng viên đều đang trong thời gian chờ", + "resilienceWaitForCooldownEffect": "Chờ trên máy chủ và thử lại khi thời gian chờ đầu tiên kết thúc", + "resilienceWaitForCooldownDesc": "Điều này chỉ ảnh hưởng đến yêu cầu hiện tại. Nó không lưu trữ trạng thái kết nối hoặc nhà cung cấp.", "resilienceEnableServerWait": "Bật tính năng chờ phía máy chủ", - "resilienceEnableServerWaitDesc": "Khi được bật, OmniRoute sẽ đợi thời gian hồi chiêu đầu tiên hết và tự động thử lại.", + "resilienceEnableServerWaitDesc": "Khi được bật, OmniRoute sẽ đợi thời gian chờ đầu tiên kết thúc và tự động thử lại.", "resilienceMaxAttempts": "Số lần thử tối đa", "resilienceMaxWaitPerAttempt": "Thời gian chờ tối đa cho mỗi lần thử", - "forcedFingerprintTitle": "Always enabled for {provider} — required for OAuth account safety; cannot be turned off.", - "forcedFingerprintBadge": "Required", - "codexSessionAffinityTitle": "Mối quan hệ phiên Codex", - "codexSessionAffinityDesc": "Giữ một cuộc trò chuyện Codex trên cùng một tài khoản trong nhiều giây như vậy. 0 vô hiệu hóa nó.", - "codexSessionAffinityTtl": "Mối quan hệ TTL (giây)", - "resetAwareQuotaCacheTitle": "Đặt lại bộ đệm hạn ngạch nhận biết", - "resetAwareQuotaCacheDesc": "Bộ nhớ đệm hạn ngạch đo từ xa chỉ dành cho việc đặt hàng nhận biết lại. Hạn ngạch preflight vẫn bảo vệ các yêu cầu. 0/0 tiếp tục tìm nạp trực tiếp.", - "resetAwareQuotaCacheTtl": "TTL mới (giây)", + "forcedFingerprintTitle": "Luôn được bật cho {provider} — bắt buộc để đảm bảo an toàn tài khoản OAuth; không thể tắt.", + "forcedFingerprintBadge": "Bắt buộc", + "resetAwareQuotaCacheTitle": "Bộ nhớ đệm hạn ngạch theo thời điểm đặt lại", + "resetAwareQuotaCacheDesc": "Chỉ lưu vào bộ nhớ đệm dữ liệu đo từ xa về hạn ngạch để sắp xếp theo thời điểm đặt lại. Việc kiểm tra trước hạn ngạch vẫn bảo vệ các yêu cầu. 0/0 sẽ tiếp tục tìm nạp theo thời gian thực.", + "resetAwareQuotaCacheTtl": "Thời gian dữ liệu được coi là mới (giây)", "resetAwareQuotaCacheMaxStale": "Thời gian cũ tối đa (giây)", "qdrantCleanupSuccess": "OK: đã xóa {count} điểm (lưu giữ: {days} ngày)", "qdrantCleanupFailed": "Dọn dẹp không thành công", "qdrantCleanupError": "Lỗi: {error}", - "vercelRelaySuccess": "__MISSING__:Vercel Relay deployed successfully", - "vercelRelayButton": "__MISSING__:Deploy Vercel Relay", - "vercelRelayModalTitle": "__MISSING__:Deploy Vercel Relay", - "vercelRelayWarning": "__MISSING__:Warning: A Vercel deployment token is required. This token will only be used to create the serverless relay and will never be stored by OmniRoute.", - "vercelRelayTokenLabel": "__MISSING__:Vercel Access Token", - "vercelRelayProjectNameLabel": "__MISSING__:Vercel Project Name", - "vercelRelayFreeTierNote": "__MISSING__:Relays are lightweight proxy endpoints deployed on Vercel's free tier to bypass local network/region limitations.", - "vercelRelayDeploying": "__MISSING__:Deploying...", - "vercelRelayDeploy": "__MISSING__:Deploy", - "homePinProviderQuotaToHome": "Pin Information to Home Page", - "homeProviderQuotaLimits": "Provider Quota Limits", - "homeProviderQuotaLimitsDesc": "Pin the Provider Quota status container (with Refresh All button) to the top of the Home page.", - "homeQuickStart": "Quick Start", - "homeQuickStartDesc": "Show the Quick Start panel on the Home page.", - "homeProviderTopology": "Provider Topology", - "homeProviderTopologyDesc": "Show the Provider Topology on the Home page.", - "codexAutoPingTitle": "Codex Quota Auto-Ping", - "codexAutoPingDesc": "Opt-in per connection: sends a tiny request right after a Codex session window resets so it isn't cold when you need it.", - "codexAutoPingWarning": "Consumes a small amount of real Codex quota on every ping. Off by default — enable only for connections you actively rely on.", - "codexAutoPingSaveError": "Failed to update Codex Auto-Ping setting", - "codexAutoPingToggleAria": "Toggle Codex quota auto-ping for {connection}", - "credentialRedaction": "__MISSING__:Credential Redaction", - "credentialRedactionDesc": "__MISSING__:Redact API keys, tokens, and secrets from context sent to providers and from responses.", - "enableCredentialRedaction": "__MISSING__:Enable credential redaction", - "enableCredentialRedactionDesc": "__MISSING__:Scrubs API keys, tokens, private keys, and JWTs from messages, tool calls, and responses." + "vercelRelaySuccess": "Đã triển khai Vercel Relay thành công", + "vercelRelayButton": "Triển khai Vercel Relay", + "vercelRelayModalTitle": "Triển khai Vercel Relay", + "vercelRelayWarning": "Cảnh báo: Cần có token triển khai Vercel. Token này chỉ được sử dụng để tạo relay không máy chủ và OmniRoute sẽ không bao giờ lưu trữ token này.", + "vercelRelayTokenLabel": "Token truy cập Vercel", + "vercelRelayProjectNameLabel": "Tên dự án Vercel", + "vercelRelayFreeTierNote": "Relay là các endpoint proxy gọn nhẹ được triển khai trên gói miễn phí của Vercel để vượt qua các hạn chế về mạng hoặc khu vực cục bộ.", + "vercelRelayDeploying": "Đang triển khai...", + "vercelRelayDeploy": "Triển khai", + "homePinProviderQuotaToHome": "Ghim thông tin vào trang chủ", + "homeProviderQuotaLimits": "Giới hạn hạn ngạch nhà cung cấp", + "homeProviderQuotaLimitsDesc": "Ghim khung trạng thái hạn ngạch nhà cung cấp (kèm nút Làm mới tất cả) lên đầu trang chủ.", + "homeQuickStart": "Bắt đầu nhanh", + "homeQuickStartDesc": "Hiển thị bảng Bắt đầu nhanh trên trang chủ.", + "homeProviderTopology": "Cấu trúc liên kết nhà cung cấp", + "homeProviderTopologyDesc": "Hiển thị cấu trúc liên kết nhà cung cấp trên trang chủ.", + "codexAutoPingTitle": "Tự động ping hạn ngạch Codex", + "codexAutoPingDesc": "Tùy chọn theo từng kết nối: gửi một yêu cầu nhỏ ngay sau khi cửa sổ phiên Codex đặt lại để kết nối sẵn sàng khi cần.", + "codexAutoPingWarning": "Mỗi lần ping sẽ dùng một lượng nhỏ hạn ngạch Codex thực. Mặc định tắt — chỉ bật cho các kết nối bạn thường xuyên sử dụng.", + "codexAutoPingSaveError": "Không thể cập nhật cài đặt tự động ping Codex", + "codexAutoPingToggleAria": "Bật hoặc tắt tự động ping hạn ngạch Codex cho {connection}", + "description": "Description", + "enable": "Enable", + "disable": "Disable", + "update": "Update", + "memoryTokenCostWarning": "Heads up: with memory enabled, OmniRoute injects up to {tokens} tokens of retrieved context into every chat request — this increases token usage and cost. To skip injection for a specific request, send the \"x-omniroute-no-memory: true\" header.", + "logToolSourcesToggle": "Log Tool Sources", + "logToolSourcesDescription": "Emit a diagnostic log line per request summarizing tool count and MCP/hosted/client source breakdown.", + "accountEmailVisibility": "Account email visibility", + "accountEmailVisibilityDesc": "Show full account emails across providers, combos, logs, quota, and playground screens. Turn this off to mask them by default.", + "customBannedSignals": "Banned Keywords", + "customBannedSignalsDesc": "Additional keywords that trigger permanent account ban detection. Built-in keywords always apply.", + "customBannedSignalsPlaceholder": "e.g. api key revoked", + "noCustomBannedSignals": "No custom keywords. Only built-in keywords are active.", + "perKeyProxyEnabled": "Enable per-key proxy assignment", + "perKeyProxyEnabledDesc": "When enabled, each provider connection can use its own proxy assignment", + "proxyPool": "Proxy Pool", + "freePool": "Free Pool", + "proxyDocumentation": "Proxy Documentation", + "proxyGlobalConfigTab": "Global Config", + "proxyPoolTab": "Proxy Pool", + "freePoolTab": "Free Pool", + "proxyDocumentationTab": "Documentation", + "proxyDocumentationScopeTitle": "Proxy scope resolution", + "proxyDocumentationScopeDescBefore": "OmniRoute resolves the outbound proxy in priority order:", + "proxyDocumentationScopeOrder": "combo → account → provider → global", + "proxyDocumentationScopeDescAfter": ". The most specific scope wins.", + "proxyDocumentationAddTitle": "Adding a custom proxy", + "proxyDocumentationAddDescBefore": "Go to the", + "proxyDocumentationAddDescMiddle": "tab → click", + "proxyDocumentationAddCta": "+ Add proxy", + "proxyDocumentationAddDescAfter": ". Fill in type (http/https/socks5), host, and port. Optionally assign it to a scope.", + "proxyDocumentationBulkTitle": "Bulk import format", + "proxyDocumentationBulkDesc": "Pipe-delimited fields:", + "proxyDocumentationSocks5DescBefore": "SOCKS5 proxies are disabled by default. Set", + "proxyDocumentationFreePoolDesc": "The Free Pool tab aggregates proxies from 1proxy, Proxifly, and IPLocate. Use ⊕ to test and promote a proxy to your registry. Only proxies that pass the connectivity test are added.", + "proxyDocumentationVercelRelayDescBefore": "The Vercel Relay is an outbound edge relay — not an inbound tunnel. Deploying one sends LLM API calls through Vercel's dynamic IPs, bypassing datacenter geo-blocks and rate limits. The relay is protected by a generated secret header", + "proxyDocumentationVercelRelayDescAfter": "Your Vercel token is used only during deploy and is never stored.", + "vercelRelayTokenRequired": "Token is required", + "vercelRelayDeployFailed": "Deploy failed", + "vercelRelayTokenHint": "Token is used only during deploy — never stored.", + "denoRelayTokenRequired": "Deno Deploy token is required", + "denoRelayOrgDomainRequired": "Organization domain is required", + "denoRelayDeployFailed": "Deno Deploy failed", + "denoRelayTokenHint": "Organization token (prefix ddo_) from console.deno.com → Organization → Settings → Organization Tokens. Used once for deploy and never stored.", + "denoRelayOrgDomainHint": "Your Deno Deploy organization's default domain (e.g. acme.deno.net). The relay will be reachable at https://..deno.net.", + "proxyFreePoolFilterProtocol": "Filter by protocol", + "proxyFreePoolProtocol": "Protocol", + "proxyFreePoolCountryPlaceholder": "Country (e.g. US)", + "proxyFreePoolFilterCountry": "Filter by country", + "proxyFreePoolMinQualityPlaceholder": "Min quality", + "proxyFreePoolMinQualityLabel": "Minimum quality score", + "proxyFreePoolSyncAll": "Sync All", + "proxyFreePoolTotal": "Total", + "proxyFreePoolInPool": "In pool", + "proxyFreePoolAvgQuality": "Avg quality", + "proxyFreePoolSelected": "{count} selected", + "proxyFreePoolAddSelected": "Add selected to pool", + "proxyFreePoolAddVisible": "Add all visible to pool", + "proxyFreePoolSource": "Source", + "proxyFreePoolHostPort": "Host:Port", + "proxyFreePoolType": "Type", + "proxyFreePoolCountry": "Country", + "proxyFreePoolQuality": "Quality", + "proxyFreePoolLatency": "Latency", + "proxyFreePoolEmpty": "No proxies found. Click Sync All to fetch from sources.", + "proxyFreePoolSearchPlaceholder": "Search host…", + "proxyFreePoolSearchLabel": "Search proxies by host", + "proxyFreePoolSortLabel": "Sort proxies", + "proxyFreePoolSortQuality": "Quality", + "proxyFreePoolSortLatency": "Latency", + "proxyFreePoolSortRecent": "Recently validated", + "proxyFreePoolListTotal": "Listed", + "proxyFreePoolLoadMore": "Load more", + "close": "Close", + "cancel": "Cancel", + "routingStrategyTitle": "Routing Strategy", + "routingStrategySubtitle": "Match 9router: account round-robin, sticky limits, and combo rotation", + "accountRoundRobin": "Round Robin", + "accountRoundRobinDesc": "Cycle through accounts to distribute load", + "comboRoundRobin": "Combo Round Robin", + "comboRoundRobinDesc": "Cycle through combo targets instead of always starting with the first", + "comboStickyLimit": "Combo Sticky Limit", + "comboStickyLimitDesc": "Calls per combo target before switching", + "routingStrategyAccountSummary": "Distributing requests across accounts with {limit} calls per account.", + "routingStrategyFillFirstSummary": "Using accounts in priority order (Fill First).", + "routingStrategyComboSummary": " Combos rotate after {limit} call(s) per target.", + "routingStrategyComboFallbackSummary": " Combos use each combo's configured strategy (default priority/fallback).", + "providerAccountRoutingTitle": "Multi-account routing", + "providerAccountRoutingDesc": "Override global account strategy for this provider (9router parity).", + "providerRoutingStrategy": "Account strategy", + "providerRoutingInheritGlobal": "Inherit global default", + "selectProviderPlaceholder": "Select provider...", + "searchProviderPlaceholder": "Search providers...", + "searchProviderAria": "Search providers", + "queueDepth": "Queue Depth", + "export": "Export", + "modelOverridesTitle": "Model Overrides", + "modelOverridesDesc": "Override provider/model capabilities used by routing and request shaping. Targets use the same provider/model form as combos.", + "searchModelOverrideTargets": "Search provider/model...", + "selectedModel": "Selected model", + "configured": "configured", + "none": "None", + "modelOverrideValuePlaceholder": "Numeric value", + "addKeyValue": "Add key value", + "noModelOverrides": "No overrides configured for this model.", + "modelOverrideLoadFailed": "Failed to load model overrides", + "modelOverrideSaved": "Model override saved", + "modelOverrideRemoved": "Model override removed", + "modelOverrideSaveFailed": "Failed to save model override", + "modelOverrideRemoveFailed": "Failed to remove model override", + "echoRequestedModelTitle": "Echo requested model name in responses", + "echoRequestedModelDesc": "When enabled, the response `model` field echoes the alias or combo name the client requested instead of the upstream model name. Fixes strict clients (e.g. Claude Desktop) that reject a response whose model does not match the request.", + "webSearchRouteTitle": "Web search routing", + "webSearchRouteDesc": "When a request includes a native web_search tool, route the whole request to this model instead of the default — useful for providers that don't implement Anthropic's web_search server tool. Leave blank to disable.", + "webSearchRoutePlaceholder": "Search or select a model…", + "paidModelPatternWarning": "This pattern only matches paid models — enable paid models or adjust the pattern.", + "logsDeleted": "{count, plural, =0 {No expired logs purged} one {Purged # expired log} other {Purged # expired logs}}", + "resetUsageData": "Reset Usage Data", + "resetUsageDataDesc": "Select how far back you want to delete usage, request logs, and analytics data. Provider configuration, connections, API keys, combos, and settings are preserved. This action cannot be undone.", + "resetUsagePeriod_5m": "5 minutes", + "resetUsagePeriod_1h": "1 hour", + "resetUsagePeriod_3h": "3 hours", + "resetUsagePeriod_6h": "6 hours", + "resetUsagePeriod_12h": "12 hours", + "resetUsagePeriod_1d": "1 day", + "resetUsagePeriod_7d": "7 days", + "resetUsagePeriod_30d": "30 days", + "resetUsagePeriod_all": "All time", + "resetUsageSuccess": "{count, plural, =0 {No usage data rows deleted} one {Reset usage data (# row deleted)} other {Reset usage data (# rows deleted)}}", + "resetUsageFailed": "Failed to reset usage data", + "reset": "Reset", + "resetting": "Resetting...", + "compressionGuidanceFullGuideLink": "Full compression guide", + "compressionGuidanceShow": "Details", + "compressionGuidanceHide": "Hide details", + "compressionGuidanceSafeDefault": "Safe default", + "compressionGuidanceCacheImpact": "Cache impact", + "tokenSaverTitle": "Token Saver", + "tokenSaverSubtitle": "Spend fewer tokens on every request.", + "tokenSaverToolOutput": "Tool output", + "tokenSaverToolOutputDesc": "Clean git, grep, ls, tree, and log output before it reaches the provider.", + "tokenSaverLlmOutput": "LLM output", + "tokenSaverLlmOutputDesc": "Inject terse response instructions without rewriting provider output.", + "tokenSaverInputCompression": "Input compression", + "tokenSaverInputCompressionDesc": "Rewrite eligible chat history while preserving code, URLs, and intent.", + "tokenSaverFineTunePrefix": "Fine-tune each engine on", + "tokenSaverFineTuneSuffix": "or combine engines per request on", + "compressionUltraEngine": "Ultra tier", + "compressionUltraEngineHeuristic": "Heuristic (Tier-A, default)", + "compressionUltraEngineSlm": "SLM (LLMLingua-2, opt-in)", + "compressionUltraSlmHint": "SLM downloads a small ONNX model on first use (cold-start) and transparently falls back to the heuristic on timeout or if unavailable.", + "compressionUltraSlmPrewarm": "Pre-warm SLM model on enable", + "compressionPreserveSystemAlways": "Always", + "compressionPreserveSystemWhenNoCache": "When no cache", + "compressionPreserveSystemNever": "Never", + "compressionLiveZoneTitle": "Cache-aligned Live Zone", + "compressionLiveZoneDesc": "Keep the compressed conversation prefix stable and process only newly appended items.", + "compressionCavemanPanelHint": "Its on/off and level are set in the panel:", + "storageDatabaseBackups": "Database backups", + "storagePurgeDataDesc": "Immediately delete all records without applying retention checks. Use with caution.", + "storageRetentionCleanup": "Retention Settings", + "storageRetentionCleanupDesc": "Configure operational record retention and database backup cleanup.", + "retentionCallDays": "Call {count}d", + "retentionAppDays": "App {count}d", + "retentionRows": "{count} rows", + "retentionCompressionAnalytics": "Compression Analytics (days)", + "retentionXpAuditLog": "XP Audit Log (days)", + "saveRetentionSettings": "Save retention settings", + "storageUsageTokenBufferDesc": "Extra tokens added to reported usage to account for system prompt overhead.", + "storageUsageTokenBufferHint": "Set to 0 to report raw provider token counts. Default: 2000.", + "storageUsageTokenBufferCurrent": "Current: {value}", + "redisLauncherTitle": "Local Redis", + "redisLauncherDesc": "One-click launch a Redis 7 container (Podman or Docker) for response cache, quota tracking, and rate limiting.", + "redisLauncherRefresh": "Refresh", + "redisLauncherStop": "Stop", + "redisLauncherLaunching": "Launching...", + "redisLauncherLaunch": "Launch Redis", + "redisLauncherContainer": "Container", + "redisLauncherRunning": "Running", + "redisLauncherReachable": "Reachable", + "redisLauncherError": "Error: {message}", + "redisLauncherHint": "Equivalent to running `omniroute redis up`. The container is named `omniroute-redis` and listens on 127.0.0.1:6379.", + "mcpAccessibilityTitle": "MCP accessibility output", + "compressionSettingsOutputStyles": "Output styles", + "compressionStylesTileTitle": "Output styles", + "cliproxyapiImportAuthTitle": "Import accounts from CLIProxyAPI", + "cliproxyapiImportAuthDesc": "Import the OAuth accounts CLIProxyAPI already saved in ~/.cli-proxy-api/ as OmniRoute connections, so you don't have to log in to each account again. Supported account types (Gemini, Codex, Claude, Antigravity, Qwen, Kimi) are imported; others are skipped.", + "cliproxyapiImportAuthButton": "Import accounts", + "responsesStateTitle": "Responses State", + "responsesStateDesc": "Control how OmniRoute forwards previous_response_id.", + "responsesStateModeLabel": "previous_response_id handling", + "responsesStateModeAuto": "Auto", + "responsesStateModeStrip": "Strip", + "responsesStateModePreserve": "Preserve", + "responsesStateHint": "Auto strips previous_response_id unless a connection explicitly enables OpenAI Responses storage. Strip is safest for stateless clients such as VS Code Custom Endpoint; context then depends on the client sending full history.", + "responsesStateSaveError": "Failed to update Responses state setting", + "resilienceComboCooldownWaitTitle": "Quota-share combo cooldown wait", + "resilienceComboCooldownWaitDesc": "For quota-share combos only: wait out a short transient cooldown and re-dispatch instead of returning a 429 immediately. Never waits on quota_exhausted.", + "resilienceComboCooldownWaitToggleDesc": "Quota-share combos only; never waits on quota_exhausted.", + "resilienceComboCooldownMaxWaitMs": "Maximum wait per attempt", + "resilienceComboCooldownBudgetMs": "Total wait budget", + "resilienceQuotaShareConcurrencyTitle": "Quota-share per-connection concurrency", + "resilienceQuotaShareConcurrencyDesc": "For quota-share combos only: when a connection sets a Max Concurrent cap, serialize concurrent requests to that subscription account so it is never flooded past its ceiling. Excess requests wait in the queue instead of getting a 429. The cap comes from each connection's Max Concurrent field; this switch only enables or disables honoring it.", + "resilienceQuotaShareConcurrencyToggleDesc": "Quota-share combos only; honors each connection's Max Concurrent cap.", + "resilienceProviderCooldownTitle": "Provider Cooldown", + "resilienceProviderCooldownScope": "All combo requests", + "resilienceProviderCooldownTrigger": "When a provider/connection fails", + "resilienceProviderCooldownEffect": "Skips the failed provider for a cooldown period before retrying", + "resilienceProviderCooldownDesc": "Prevents subsequent requests from re-walking the same failing providers. Cooldown scales exponentially with consecutive failures.", + "resilienceProviderCooldownEnabled": "Enable global provider cooldown", + "resilienceProviderCooldownEnabledDesc": "When enabled, failed providers are tracked globally and skipped for a cooldown period.", + "resilienceProviderCooldownMin": "Minimum cooldown", + "resilienceProviderCooldownMax": "Maximum cooldown", + "sessionAffinityTitle": "Session affinity", + "sessionAffinityDesc": "Keeps one conversation on the same account for this many seconds, for any provider. 0 disables it.", + "sessionAffinityTtl": "Affinity TTL (seconds)", + "deployRelayButton": "Deploy Relay", + "denoRelayButton": "Deploy Deno Relay", + "denoRelayModalTitle": "Deploy Deno Relay", + "denoRelayWarning": "Warning: A Deno Deploy organization token is required. This token will only be used to create the relay app and will never be stored by OmniRoute.", + "denoRelayTokenLabel": "Deno Deploy Organization Token", + "denoRelayOrgDomainLabel": "Organization Domain", + "denoRelayProjectNameLabel": "Deno App Name", + "denoRelayFreeTierNote": "Deno Deploy v2 runs on a global edge network. Free tier: 1M requests & 100GiB outbound traffic per month, no per-request CPU limits, up to 20 active apps & 50 custom domains.", + "denoRelayDeploying": "Deploying...", + "denoRelayDeploy": "Deploy", + "cloudflareRelaySuccess": "Cloudflare Relay deployed successfully", + "cloudflareRelayButton": "Deploy Cloudflare Relay", + "cloudflareRelayModalTitle": "Deploy Cloudflare Worker Relay", + "cloudflareRelayWarning": "Deploys a Cloudflare Worker that proxies LLM requests through Cloudflare's edge network — masking the host IP behind dynamic Cloudflare addresses. The Worker enforces a one-time auth secret so the public workers.dev URL cannot be reused as an open relay.", + "cloudflareRelayTokenHowto": "Create the API token under My Profile -> API Tokens -> Create Token -> Custom Token -> Account / Workers Scripts / Edit.", + "cloudflareRelayAccountIdLabel": "Cloudflare Account ID", + "cloudflareRelayAccountIdHint": "Found on the right side of the Cloudflare dashboard overview page.", + "cloudflareRelayApiTokenLabel": "Cloudflare API Token", + "cloudflareRelayApiTokenHint": "Requires 'Workers Scripts: Edit' permission. The token is used only at deploy time and is never stored.", + "cloudflareRelayProjectNameLabel": "Worker Name", + "cloudflareRelayFreeTierNote": "Free tier: 100,000 requests/day per Cloudflare account.", + "cloudflareRelayDeploying": "Deploying...", + "cloudflareRelayDeploy": "Deploy", + "cloudflareRelayCredsRequired": "Account ID and API Token are required", + "cloudflareRelayDeployFailed": "Deploy failed", + "modelLockout": "Model Lockout", + "modelLockoutPageDescription": "Configure which HTTP error codes trigger per-model lockout and control the cooldown behavior.", + "modelLockoutEnabled": "Enable Model Lockout", + "modelLockoutEnabledDescription": "When enabled, models that fail with configured error codes are temporarily locked to prevent retry loops.", + "modelLockoutErrorCodes": "Error Codes", + "modelLockoutErrorCodesDescription": "HTTP status codes that trigger model lockout. Type a code and click Add, or select from suggestions.", + "modelLockoutBaseCooldown": "Base Cooldown (ms)", + "modelLockoutBaseCooldownDescription": "Initial cooldown duration in milliseconds before a model can be retried.", + "modelLockoutMaxCooldown": "Max Cooldown (ms)", + "modelLockoutMaxCooldownDescription": "Maximum cooldown duration in milliseconds. Prevents excessively long lockouts.", + "modelLockoutExponentialBackoff": "Exponential Backoff", + "modelLockoutExponentialBackoffDescription": "When enabled, each consecutive failure increases the cooldown duration exponentially.", + "modelLockoutMaxBackoffSteps": "Max Backoff Steps", + "modelLockoutMaxBackoffStepsDescription": "Maximum number of backoff steps before the cooldown stops growing. The Max Cooldown cap is reached first in most configurations, making this a safety ceiling for when Max Cooldown is raised.", + "disableSessionStickiness": "Disable session stickiness", + "disableSessionStickinessDesc": "Round-robin and random combos rotate to a different connection on every request instead of pinning a whole conversation to one connection by the first-message hash. Leave off to preserve prompt-cache hits for multi-turn chats. Per-combo overrides take precedence.", + "credentialRedaction": "Credential Redaction", + "credentialRedactionDesc": "Redact API keys, tokens, and secrets from context sent to providers and from responses.", + "enableCredentialRedaction": "Enable credential redaction", + "enableCredentialRedactionDesc": "Scrubs API keys, tokens, private keys, and JWTs from messages, tool calls, and responses." }, "contextRtk": { "title": "RTK Engine", - "description": "Command-aware compression for tool output, terminal logs and build results.", - "enabled": "Enabled", - "intensity": "Intensity", - "intensityMinimal": "Minimal", - "intensityStandard": "Standard", - "intensityAggressive": "Aggressive", - "toolResults": "Tool results", - "assistantMessages": "Assistant messages", - "codeBlocks": "Code blocks", + "description": "Nén nhận biết lệnh cho đầu ra của công cụ, nhật ký terminal và kết quả bản dựng.", + "enabled": "Đã bật", + "intensity": "Cường độ", + "intensityMinimal": "Tối thiểu", + "intensityStandard": "Tiêu chuẩn", + "intensityAggressive": "Mạnh", + "toolResults": "Kết quả của công cụ", + "assistantMessages": "Tin nhắn của trợ lý", + "codeBlocks": "Khối mã", "filterCatalog": "Danh mục bộ lọc", - "filterCatalogDesc": "Bộ lọc đầu ra có sẵn theo danh mục", + "filterCatalogDesc": "Các bộ lọc đầu ra có sẵn theo danh mục", "guidedConfig": "Cấu hình", - "guidedConfigDesc": "Điều chỉnh cách RTK lọc đầu ra thiết bị đầu cuối của bạn", - "maxLines": "Max lines", - "maxChars": "Max chars", - "deduplicateThreshold": "Ngưỡng trùng lặp", + "guidedConfigDesc": "Điều chỉnh cách RTK lọc đầu ra của terminal của bạn", + "maxLines": "Số dòng tối đa", + "maxChars": "Số ký tự tối đa", + "deduplicateThreshold": "Ngưỡng khử trùng lặp", "customFilters": "Bộ lọc tùy chỉnh", "detectedType": "Loại được phát hiện", - "confidence": "sự tự tin", + "confidence": "Độ tin cậy", "beforeAfter": "Trước / Sau", - "trustProjectFilters": "Bộ lọc dự án tin cậy", - "rawOutputRetention": "Duy trì đầu ra thô", - "rawOutputNever": "không bao giờ", - "rawOutputFailures": "Thất bại", + "trustProjectFilters": "Tin cậy các bộ lọc của dự án", + "rawOutputRetention": "Lưu giữ đầu ra thô", + "rawOutputNever": "Không bao giờ", + "rawOutputFailures": "Khi thất bại", "rawOutputAlways": "Luôn luôn", - "rawOutputMaxBytes": "Số byte tối đa đầu ra thô", - "filterTesting": "Filter Testing", - "pasteOutput": "Paste tool output to test filtering...", - "presetHigh": "hung hãn", - "presetLow": "Ánh sáng", - "presetMaxChars": "Ký tự đầu ra tối đa", - "presetMaxLines": "Dòng đầu ra tối đa", + "rawOutputMaxBytes": "Số byte tối đa của đầu ra thô", + "filterTesting": "Kiểm thử bộ lọc", + "pasteOutput": "Dán đầu ra công cụ để kiểm thử bộ lọc...", + "presetHigh": "Mạnh", + "presetLow": "Nhẹ", + "presetMaxChars": "Số ký tự đầu ra tối đa", + "presetMaxLines": "Số dòng đầu ra tối đa", "presetMedium": "Tiêu chuẩn", - "run": "Run", - "result": "Result", - "previewEmpty": "Run a sample to preview RTK output.", - "detected": "Detected", - "masterSwitchOffAlert": "__MISSING__:Token Saver master switch is OFF — these settings will not affect requests until you turn it on from the Endpoint page.", - "tokensFiltered": "Tokens filtered", - "filtersActive": "Filters active", - "requests": "Requests", - "avgSavings": "Avg savings", + "run": "Chạy", + "result": "Kết quả", + "previewEmpty": "Chạy một mẫu để xem trước đầu ra RTK.", + "detected": "Đã phát hiện", + "masterSwitchOffAlert": "Công tắc chính Token Saver đang TẮT — các cài đặt này sẽ không ảnh hưởng đến yêu cầu cho đến khi bạn bật công tắc này trong Cài đặt nén.", + "tokensFiltered": "Số token đã lọc", + "filtersActive": "Bộ lọc đang hoạt động", + "requests": "Yêu cầu", + "avgSavings": "Tiết kiệm trung bình", "simpleMode": "Đơn giản", "advancedMode": "Nâng cao", - "searchFilters": "Bộ lọc tìm kiếm...", - "tooltipDedup": "Làm thế nào mạnh mẽ để loại bỏ các dòng lặp đi lặp lại.", - "tooltipMaxChars": "Ký tự tối đa trên mỗi khối đầu ra.", - "tooltipMaxLines": "Các dòng tối đa cần tránh khỏi đầu ra lệnh. Phần thừa sẽ bị cắt bớt." + "searchFilters": "Tìm kiếm bộ lọc...", + "tooltipDedup": "Mức độ triệt để khi loại bỏ các dòng lặp lại.", + "tooltipMaxChars": "Số ký tự tối đa trên mỗi khối đầu ra.", + "tooltipMaxLines": "Số dòng tối đa cần giữ lại từ đầu ra của lệnh. Phần thừa sẽ bị cắt bớt.", + "learnDiscoverTitle": "Learn & Discover filters", + "learnDiscoverDesc": "Mine your captured command output (Raw Output retention must be on) to suggest new RTK filters. Suggestions only — you review and save them.", + "discoverHeading": "Discover repeated noise", + "discoverButton": "Scan samples", + "discoverScanning": "Scanning…", + "discoverEmpty": "No repeated noise found. Enable Raw Output retention and run a few commands first.", + "discoverSamples": "{count} sample(s) scanned", + "discoverHits": "{hits}× across samples", + "learnHeading": "Learn a filter for a command", + "learnCommandPlaceholder": "e.g. npm install", + "learnButton": "Suggest filter", + "learnEmpty": "No suggestion yet. Type a command you have run and scan.", + "learnSamplesUsed": "Learned from {count} matching sample(s)", + "suggestionError": "Could not load suggestions. Check management auth and try again.", + "tomlImportTitle": "Import RTK TOML filters", + "tomlImportDesc": "Validate RTK TOML schema v1 filters and install them globally. Installation writes DATA_DIR/rtk/filters.toml; existing files are replaced only after explicit confirmation.", + "tomlChooseFile": "Choose a TOML file", + "tomlImportPlaceholder": "Paste RTK filters.toml content here...", + "tomlValidate": "Validate", + "tomlValidating": "Validating…", + "tomlInstall": "Install globally", + "tomlInstalling": "Installing…", + "tomlConfirmOverwrite": "Replace the existing global file and create a backup", + "tomlValidationPassed": "Validation passed", + "tomlValidationFailed": "Validation completed with failing inline tests", + "tomlValidationSummary": "{filters} filter(s), {tests} inline test(s)", + "tomlInstalled": "Installed at {path}", + "tomlBackupCreated": "A backup of the previous file was created.", + "tomlTestCount": "{count} test(s)", + "tomlTestPassed": "Passed", + "tomlTestFailed": "Failed", + "tomlImportError": "Could not process the RTK TOML file.", + "tomlFileReadError": "Could not read the selected TOML file." }, "contextCombos": { - "title": "Compression Combos", - "description": "Define how engines are combined for different routing scenarios.", - "createCombo": "Create Compression Combo", - "editCombo": "Edit", - "deleteCombo": "Delete", - "deleteConfirm": "Delete this compression combo?", - "pipeline": "Pipeline", - "addStep": "Add Step", - "removeStep": "Remove", - "name": "Name", - "descriptionField": "Description", - "languagePacks": "Language Packs", - "outputMode": "Output Mode", - "assignToRouting": "Assign to Routing Combos", - "noAssignments": "No routing combos available", - "default": "Default", - "setAsDefault": "Set as Default", - "save": "Save", - "cancel": "Cancel", - "enabled": "Enabled" + "title": "Tổ hợp nén", + "description": "Xác định cách kết hợp các công cụ cho những tình huống định tuyến khác nhau.", + "createCombo": "Tạo tổ hợp nén", + "editCombo": "Chỉnh sửa", + "deleteCombo": "Xóa", + "deleteConfirm": "Xóa tổ hợp nén này?", + "pipeline": "Quy trình", + "addStep": "Thêm bước", + "removeStep": "Loại bỏ", + "name": "Tên", + "descriptionField": "Mô tả", + "languagePacks": "Gói ngôn ngữ", + "outputMode": "Chế độ đầu ra", + "assignToRouting": "Gán cho các tổ hợp định tuyến", + "noAssignments": "Không có tổ hợp định tuyến nào khả dụng", + "default": "Mặc định", + "setAsDefault": "Đặt làm mặc định", + "save": "Lưu", + "cancel": "Hủy", + "enabled": "Đã bật" }, "contextCaveman": { - "title": "Caveman Engine", - "description": "Rule-based message compression, language packs, analytics and output mode controls.", + "title": "Công cụ Caveman", + "description": "Nén tin nhắn dựa trên quy tắc, các gói ngôn ngữ, phân tích và kiểm soát chế độ đầu ra.", "advancedConfig": "Cấu hình nâng cao", "advancedConfigDesc": "Tinh chỉnh hành vi nén", - "aggressiveSettings": "Cài đặt linh hoạt", - "aggressiveSettingsDesc": "Nén tối đa với sự đánh đổi chất lượng tiềm năng", - "requests": "Requests", - "tokensSaved": "Tokens saved", - "savingsPercent": "Savings %", - "avgLatency": "Avg latency", - "languagePacks": "Language Packs", - "languagePacksDesc": "Enable compression rules for specific languages.", + "aggressiveSettings": "Cài đặt nén mạnh", + "aggressiveSettingsDesc": "Nén tối đa nhưng có thể phải đánh đổi về mặt chất lượng", + "requests": "Yêu cầu", + "tokensSaved": "Số token đã tiết kiệm", + "savingsPercent": "Tỷ lệ tiết kiệm (%)", + "avgLatency": "Độ trễ trung bình", + "languagePacks": "Gói ngôn ngữ", + "languagePacksDesc": "Bật các quy tắc nén cho các ngôn ngữ cụ thể.", "labelAutoTrigger": "Tự động nén khi ngữ cảnh vượt quá", "labelCompressionRate": "Cường độ nén", - "labelMaxTokens": "Mã thông báo mục tiêu cho mỗi tin nhắn", + "labelMaxTokens": "Token mục tiêu cho mỗi tin nhắn", "labelMinLength": "Độ dài tin nhắn tối thiểu", - "labelMinSavings": "Mã thông báo tối thiểu để lưu", - "enabled": "Enabled", - "autoDetect": "Auto-detect language", - "rulesCount": "{count} rules", - "inputCompressionTitle": "__MISSING__:Input compression", - "inputCompressionDesc": "__MISSING__:Rewrite chat history with shorter wording. Reduces input tokens by ~50%.", - "analyticsTitle": "Compression Analytics", - "noAnalytics": "No compression analytics yet.", + "labelMinSavings": "Số token tối thiểu cần tiết kiệm", + "enabled": "Đã bật", + "autoDetect": "Tự động phát hiện ngôn ngữ", + "rulesCount": "{count} quy tắc", + "inputCompressionTitle": "Nén đầu vào", + "inputCompressionDesc": "Viết lại lịch sử trò chuyện với từ ngữ ngắn gọn hơn. Giảm khoảng 50% lượng token đầu vào.", + "analyticsTitle": "Phân tích nén", + "noAnalytics": "Chưa có phân tích nén nào.", "outputMode": "Chế độ đầu ra", - "outputModeDesc": "Instructs the LLM to respond in a terse, compact format.", - "outputModeTitle": "Output Mode", + "outputModeDesc": "Kiểm soát cách hiển thị của đầu ra đã nén", + "outputModeTitle": "Chế độ đầu ra", "quickSettings": "Cài đặt nhanh", - "quickSettingsDesc": "Cài đặt nén cơ bản để bắt đầu", - "autoClarity": "Auto-Clarity Bypass", - "bypassConditions": "Bypass conditions", - "bypassConditionsList": "bảo mật, không thể đảo ngược, làm rõ, nhạy cảm với trật tự", + "quickSettingsDesc": "Các cài đặt nén cơ bản để bắt đầu sử dụng", + "autoClarity": "Bỏ qua Auto-Clarity", + "bypassConditions": "Điều kiện bỏ qua", + "bypassConditionsList": "bảo mật, không thể đảo ngược, làm rõ, nhạy cảm với thứ tự", "simpleMode": "Đơn giản", "advancedMode": "Nâng cao", "tooltipAutoTrigger": "Tự động nén khi ngữ cảnh vượt quá kích thước này.", - "tooltipCompressionRate": "0,0 = không có, 1,0 = tối đa. 0,5 = cân bằng.", - "tooltipMaxTokens": "Số lượng mã thông báo mục tiêu sau khi nén. Thấp hơn = hung hăng hơn.", - "tooltipMinLength": "Tin nhắn ngắn hơn thế này sẽ không được nén. Thấp hơn = nén nhiều hơn.", - "tooltipMinSavings": "Chỉ nén nếu nó lưu ít nhất nhiều mã thông báo này.", - "ultraSettings": "Cài đặt cực cao", - "ultraSettingsDesc": "Nén ngữ nghĩa được hỗ trợ bởi SLM", + "tooltipCompressionRate": "0.0 = không nén, 1.0 = tối đa. 0.5 = cân bằng.", + "tooltipMaxTokens": "Số lượng token mục tiêu sau khi nén. Thấp hơn = nén mạnh hơn.", + "tooltipMinLength": "Tin nhắn ngắn hơn mức này sẽ không được nén. Thấp hơn = nén nhiều hơn.", + "tooltipMinSavings": "Chỉ nén nếu tiết kiệm được ít nhất ngần này token.", + "ultraSettings": "Cài đặt tối đa", + "ultraSettingsDesc": "Nén ngữ nghĩa sử dụng SLM", "preview": { - "lite": "Respond concise. Preserve technical terms, code, errors, URLs, and identifiers.", - "full": "Respond terse and compact. Preserve all technical substance.", - "ultra": "Respond ultra terse with common technical abbreviations. Preserve exact symbols." + "lite": "Phản hồi ngắn gọn. Giữ nguyên thuật ngữ kỹ thuật, mã, lỗi, URL và mã định danh.", + "full": "Phản hồi cực ngắn và gọn. Giữ nguyên toàn bộ nội dung kỹ thuật.", + "ultra": "Phản hồi siêu ngắn gọn với các từ viết tắt kỹ thuật phổ biến. Giữ nguyên các ký hiệu chính xác." } }, "translator": { - "title": "Người phiên dịch", - "metaTitle": "Sân chơi phiên dịch | OmniRoute", - "metaDescription": "Gỡ lỗi, kiểm tra và trực quan hóa bản dịch định dạng API giữa các nhà cung cấp", - "playgroundTitle": "Sân chơi phiên dịch", + "title": "Trình dịch", + "metaTitle": "Khu thử nghiệm trình dịch | OmniRoute", + "metaDescription": "Gỡ lỗi, kiểm tra và trực quan hóa việc chuyển đổi định dạng API giữa các nhà cung cấp", + "playgroundTitle": "Khu thử nghiệm trình dịch", "playground": "Sân chơi", - "realtime": "Hoạt động dịch thời gian thực", + "realtime": "Hoạt động dịch theo thời gian thực", "chatTester": "Trình kiểm tra trò chuyện", - "testBench": "Ghế thử nghiệm", - "liveMonitor": "Màn hình trực tiếp", - "modeDescriptionPlayground": "Dán bất kỳ nội dung yêu cầu API nào và xem cách OmniRoute dịch nó giữa các định dạng nhà cung cấp (OpenAI ↔ Claude ↔ Gemini ↔ API phản hồi)", + "testBench": "Bàn thử nghiệm", + "liveMonitor": "Giám sát trực tiếp", + "modeDescriptionPlayground": "Dán bất kỳ phần thân của yêu cầu API nào và xem cách OmniRoute dịch giữa các định dạng nhà cung cấp (OpenAI ↔ Claude ↔ Gemini ↔ Responses API)", "modeDescriptionChatTester": "Gửi các yêu cầu trò chuyện thực tế thông qua OmniRoute và kiểm tra toàn bộ hành trình: đầu vào, yêu cầu đã dịch, phản hồi của nhà cung cấp và đầu ra đã dịch.", "modeDescriptionTestBench": "Chạy các kịch bản được xác định trước và so sánh khả năng tương thích giữa các nhà cung cấp và mô hình.", - "modeDescriptionLiveMonitor": "Xem các sự kiện dịch thuật trong thời gian thực khi các yêu cầu chảy qua OmniRoute.", + "modeDescriptionLiveMonitor": "Xem các sự kiện dịch theo thời gian thực khi các yêu cầu đi qua OmniRoute.", "modeDescriptionFallback": "Gỡ lỗi, kiểm tra và trực quan hóa cách OmniRoute dịch các yêu cầu API giữa các nhà cung cấp.", "recentTranslations": "Bản dịch gần đây", "noTranslations": "Chưa có bản dịch nào", "source": "Nguồn", - "target": "Mục tiêu", - "time": "thời gian", - "model": "người mẫu", + "target": "Đích", + "time": "Thời gian", + "model": "Mô hình", "status": "Trạng thái", "latency": "Độ trễ", "totalTranslations": "Tổng số bản dịch", - "successful": "thành công", + "successful": "Thành công", "errors": "Lỗi", "avgLatency": "Độ trễ trung bình", "millisecondsShort": "{value}ms", "notAvailableSymbol": "—", - "liveAutoRefreshing": "Trực tiếp - Tự động làm mới", + "liveAutoRefreshing": "Trực tiếp — Tự động làm mới", "paused": "Đã tạm dừng", - "eventsAppearHint": "Các sự kiện dịch xuất hiện ở đây khi các yêu cầu chuyển qua OmniRoute. Sử dụng bất kỳ phương pháp nào sau đây để tạo sự kiện:", + "eventsAppearHint": "Các sự kiện dịch sẽ xuất hiện ở đây khi các yêu cầu đi qua OmniRoute. Sử dụng bất kỳ phương pháp nào sau đây để tạo sự kiện:", "chatTesterTab": "Tab Trình kiểm tra trò chuyện", - "testBenchTab": "Tab Bench thử nghiệm", - "externalApiCalls": "Lệnh gọi API bên ngoài", + "testBenchTab": "Tab Bàn thử nghiệm", + "externalApiCalls": "Các cuộc gọi API bên ngoài", "ideCliIntegrations": "Tích hợp IDE/CLI", - "inMemoryNote": "Lưu ý: Các sự kiện được lưu trong bộ nhớ và được đặt lại khi máy chủ khởi động lại.", - "ok": "được rồi", - "errorShort": "LỖI", - "formatConverter": "Trình chuyển đổi định dạng", - "formatConverterDescription": "Dán hoặc nhập nội dung yêu cầu JSON. Trình dịch sẽ tự động phát hiện định dạng nguồn và chuyển đổi nó sang định dạng đích. Sử dụng tính năng này để gỡ lỗi cách OmniRoute dịch các yêu cầu giữa các định dạng (OpenAI ↔ Claude ↔ Gemini ↔ API phản hồi).", - "translationPathHubSpoke": "{source} → OpenAI (trung cấp) → {target}", - "translationPathDirect": "{source} → {target} (người dịch trực tiếp)", - "translationPathPassthrough": "Cùng một định dạng - không cần dịch", - "openaiIntermediatePanel": "Trung cấp OpenAI", - "autoFeaturesTitle": "OmniRoute tự động làm gì", + "inMemoryNote": "Lưu ý: Các sự kiện được lưu trong bộ nhớ và sẽ được đặt lại khi máy chủ khởi động lại.", + "ok": "OK", + "errorShort": "ERR", + "formatConverter": "Bộ chuyển đổi định dạng", + "formatConverterDescription": "Dán hoặc nhập phần thân của yêu cầu JSON. Trình dịch sẽ tự động phát hiện định dạng nguồn và chuyển đổi sang định dạng đích. Sử dụng tính năng này để gỡ lỗi cách OmniRoute dịch các yêu cầu giữa các định dạng (OpenAI ↔ Claude ↔ Gemini ↔ Responses API).", + "translationPathHubSpoke": "{source} → OpenAI (trung gian) → {target}", + "translationPathDirect": "{source} → {target} (trình dịch trực tiếp)", + "translationPathPassthrough": "Cùng định dạng — không cần dịch", + "openaiIntermediatePanel": "Trung gian OpenAI", + "autoFeaturesTitle": "Những gì OmniRoute tự động thực hiện", "autoFeaturesCount": "8 tính năng", - "featureReasoningCache": "Bộ đệm lý luận", - "featureReasoningCacheDesc": "Tiêm lại Reason_content được lưu trong bộ nhớ đệm cho các mô hình chế độ tư duy (DeepSeek V4, Kimi K2, Qwen) khi khách hàng bỏ qua nó khỏi lịch sử hội thoại.", - "featureSchemaCoercion": "Lược đồ cưỡng bức", - "featureSchemaCoercionDesc": "Sửa các lược đồ công cụ bị hỏng: thêm các Thuộc tính bổ sung bị thiếu, loại bỏ các mô tả dài, chuẩn hóa các đối tượng lồng nhau.", - "featureRoleNormalization": "Bình thường hóa vai trò", - "featureRoleNormalizationDesc": "Nhà phát triển bản đồ→hệ thống dành cho các mục tiêu không thuộc OpenAI. Hệ thống bản đồ→người dùng cho các kiểu máy không hỗ trợ vai trò hệ thống.", - "featureToolCallIds": "Chuẩn hóa ID cuộc gọi công cụ", - "featureToolCallIdsDesc": "Tạo ID tool_call duy nhất khi bị thiếu. Chuẩn hóa thành định dạng 9 ký tự cho các nhà cung cấp như Mistral.", - "featureMissingToolResponse": "Công cụ phản hồi tiêm", - "featureMissingToolResponseDesc": "Chèn các thông báo tool_result trống khi khách hàng gửi tool_calls mà không có phản hồi tương ứng.", - "featureThinkingBudget": "Suy nghĩ về ngân sách", - "featureThinkingBudgetDesc": "Tự động quản lý cấu hình tư duy. Loại bỏ các tham số suy nghĩ khi tin nhắn cuối cùng không phải từ người dùng.", + "featureReasoningCache": "Bộ đệm suy luận", + "featureReasoningCacheDesc": "Chèn lại `reasoning_content` đã lưu trong bộ đệm cho các mô hình chế độ suy nghĩ (DeepSeek V4, Kimi K2, Qwen) khi máy khách bỏ qua nó khỏi lịch sử hội thoại.", + "featureSchemaCoercion": "Ép kiểu lược đồ", + "featureSchemaCoercionDesc": "Sửa các lược đồ công cụ bị lỗi: thêm các `additionalProperties` bị thiếu, làm sạch các mô tả dài, chuẩn hóa các đối tượng lồng nhau.", + "featureRoleNormalization": "Chuẩn hóa vai trò", + "featureRoleNormalizationDesc": "Ánh xạ developer → system cho các mục tiêu không phải OpenAI. Ánh xạ system → user cho các mô hình không hỗ trợ vai trò system.", + "featureToolCallIds": "Chuẩn hóa ID gọi công cụ", + "featureToolCallIdsDesc": "Tự động tạo các ID `tool_call` duy nhất khi bị thiếu. Chuẩn hóa thành định dạng 9 ký tự cho các nhà cung cấp như Mistral.", + "featureMissingToolResponse": "Chèn phản hồi công cụ", + "featureMissingToolResponseDesc": "Chèn các tin nhắn `tool_result` trống khi máy khách gửi `tool_calls` mà không có phản hồi tương ứng.", + "featureThinkingBudget": "Ngân sách suy luận", + "featureThinkingBudgetDesc": "Tự động quản lý cấu hình tư duy. Loại bỏ các tham số tư duy khi tin nhắn cuối cùng không phải từ người dùng.", "featureDirectPaths": "Đường dẫn dịch trực tiếp", - "featureDirectPathsDesc": "Một số cặp định dạng (Claude→Gemini) có trình dịch trực tiếp bỏ qua trung tâm OpenAI, tạo ra kết quả đầu ra chính xác hơn.", + "featureDirectPathsDesc": "Một số cặp định dạng (Claude→Gemini) có bộ dịch trực tiếp bỏ qua trung tâm OpenAI, tạo ra đầu ra chính xác hơn.", "featureImageMapping": "Ánh xạ kích thước hình ảnh", "featureImageMappingDesc": "Dịch các quy ước về kích thước hình ảnh giữa các định dạng API (ví dụ: cấp độ chi tiết OpenAI → kích thước Gemini).", - "input": "đầu vào", - "output": "đầu ra", + "input": "Đầu vào", + "output": "Đầu ra", "auto": "Tự động", "swapFormats": "Hoán đổi định dạng", "translateAction": "Dịch", "clear": "Xóa", - "inputPlaceholder": "Dán nội dung yêu cầu tại đây hoặc chọn mẫu bên dưới...", + "inputPlaceholder": "Dán phần thân thô của yêu cầu tại đây hoặc chọn một mẫu bên dưới...", "exampleTemplates": "Mẫu ví dụ", - "exampleTemplatesHint": "- Bấm để tải", - "templateLoadHint": "Mẫu tải yêu cầu ở định dạng {format}. Thay đổi định dạng nguồn để tải ở định dạng khác.", - "compatibilityTester": "Trình kiểm tra khả năng tương thích", + "exampleTemplatesHint": "— Nhấp để tải", + "templateLoadHint": "Mẫu này tải yêu cầu ở định dạng {format}. Thay đổi Định dạng nguồn để tải ở định dạng khác.", + "compatibilityTester": "Trình kiểm tra tính tương thích", "compatibilityReport": "Báo cáo tương thích", - "testBenchDescription": "Chạy các kịch bản được xác định trước (Trò chuyện đơn giản, Gọi công cụ, v.v.) để xác minh khả năng tương thích của bản dịch và nhà cung cấp. Chọn định dạng nguồn và nhà cung cấp mục tiêu, sau đó chạy tất cả các thử nghiệm để xem tỷ lệ phần trăm tương thích. Sử dụng công cụ này để tìm những tính năng nào hoạt động giữa các nhà cung cấp.", + "testBenchDescription": "Chạy các kịch bản được xác định trước (Trò chuyện đơn giản, Gọi công cụ, v.v.) để xác minh khả năng tương thích của bản dịch và nhà cung cấp. Chọn định dạng nguồn và nhà cung cấp mục tiêu, sau đó chạy tất cả bài kiểm tra để xem tỷ lệ phần trăm tương thích. Sử dụng tính năng này để xác định những tính năng nào hoạt động trên nhiều nhà cung cấp.", "targetProvider": "Nhà cung cấp mục tiêu", - "runAllTests": "Chạy tất cả các bài kiểm tra", - "runTest": "Chạy thử nghiệm", + "runAllTests": "Chạy tất cả kiểm tra", + "runTest": "Chạy kiểm tra", "reRun": "Chạy lại", "running": "Đang chạy...", - "passed": "đã vượt qua", + "passed": "đạt", "failed": "thất bại", "passedIconLabel": "✅ Đạt", - "chunks": "khối", + "chunks": "phân đoạn", "scenarioSimpleChat": "Trò chuyện đơn giản", "scenarioToolCalling": "Gọi công cụ", "scenarioMultiTurn": "Nhiều lượt", - "scenarioThinking": "suy nghĩ", + "scenarioThinking": "Tư duy", "scenarioSystemPrompt": "Lời nhắc hệ thống", "scenarioStreaming": "Truyền phát", "templateNames": { "simple-chat": "Trò chuyện đơn giản", "tool-calling": "Gọi công cụ", "multi-turn": "Nhiều lượt", - "thinking": "suy nghĩ", + "thinking": "Tư duy", "system-prompt": "Lời nhắc hệ thống", "streaming": "Truyền phát", - "vision": "Tầm nhìn", - "schema-coercion": "Lược đồ cưỡng bức" + "vision": "Thị giác", + "schema-coercion": "Ép kiểu lược đồ" }, "templateDescriptions": { "simple-chat": "Tin nhắn văn bản cơ bản", - "tool-calling": "Lệnh gọi hàm/công cụ", - "multi-turn": "Đối thoại với lịch sử", - "thinking": "Suy nghĩ/lý luận mở rộng", + "tool-calling": "Gọi hàm/công cụ", + "multi-turn": "Hội thoại có lịch sử", + "thinking": "Tư duy / lập luận mở rộng", "system-prompt": "Hướng dẫn hệ thống phức tạp", - "streaming": "Yêu cầu phát trực tuyến SSE", + "streaming": "Yêu cầu truyền phát SSE", "vision": "Yêu cầu đa phương thức với đầu vào hình ảnh", - "schema-coercion": "Thực thi lược đồ JSON/đầu ra có cấu trúc" + "schema-coercion": "Thực thi đầu ra có cấu trúc / lược đồ JSON" }, "templatePayloads": { "simpleChat": { @@ -5790,115 +6612,188 @@ }, "toolCalling": { "userWeather": "Thời tiết ở São Paulo thế nào?", - "toolDescription": "Nhận thời tiết hiện tại cho một địa điểm", + "toolDescription": "Lấy thời tiết hiện tại cho một địa điểm", "cityNameDescription": "Tên thành phố" }, "multiTurn": { - "system": "Bạn là một trợ lý mã hóa.", - "userInitial": "Viết hàm sắp xếp một mảng trong Python.", - "assistantExample": "Đây là một chức năng sắp xếp đơn giản: ``` con trăn\ndef sắp xếp_array(arr): trả về đã sắp xếp(arr)\n```", + "system": "Bạn là một trợ lý lập trình.", + "userInitial": "Viết một hàm để sắp xếp một mảng trong Python.", + "assistantExample": "Dưới đây là một hàm sắp xếp đơn giản: ```python\ndef sort_array(arr): return sorted(arr)\n```", "userFollowUp": "Bây giờ hãy sắp xếp nó theo thứ tự giảm dần." }, "thinking": { "question": "Tổng của 100 số nguyên tố đầu tiên là bao nhiêu?" }, "systemPrompt": { - "systemInstruction": "Bạn là một kỹ sư phần mềm cao cấp chuyên về hệ thống phân tán. Trả lời các câu hỏi một cách chính xác bằng cách sử dụng các phương pháp hay nhất trong ngành. Luôn cung cấp các ví dụ về mã khi có liên quan. Định dạng câu trả lời của bạn bằng cách sử dụng markdown.", - "question": "Làm cách nào để triển khai mẫu ngắt mạch?" + "systemInstruction": "Bạn là một kỹ sư phần mềm cao cấp chuyên về các hệ thống phân tán. Hãy trả lời các câu hỏi một cách ngắn gọn bằng cách sử dụng các thực hành tốt nhất trong ngành. Luôn cung cấp các ví dụ mã khi có liên quan. Định dạng câu trả lời của bạn bằng markdown.", + "question": "Làm cách nào để triển khai mẫu ngắt mạch (circuit breaker)?" }, "streaming": { "prompt": "Kể cho tôi nghe một câu chuyện ngắn về một robot học vẽ." }, "vision": { "system": "Bạn là một trợ lý mô tả hình ảnh một cách chính xác.", - "userPrompt": "Những gì được thể hiện trong hình ảnh này?", + "userPrompt": "Hình ảnh này hiển thị gì?", "imageUrl": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/PNG_transparency_demonstration_1.png/600px-PNG_transparency_demonstration_1.png" }, "schemaCoercion": { - "userPrompt": "Tra cứu thời tiết ở Tokyo bằng cách sử dụng các đơn vị số liệu và bao gồm thông tin chi tiết theo giờ.", - "toolDescription": "Tìm nạp thời tiết cho một thành phố với các tùy chọn có cấu trúc.", + "userPrompt": "Tra cứu thời tiết ở Tokyo bằng đơn vị hệ mét và bao gồm thông tin chi tiết theo giờ.", + "toolDescription": "Lấy thông tin thời tiết cho một thành phố với các tùy chọn có cấu trúc.", "cityDescription": "Thành phố cần truy vấn, ví dụ: 'Tokyo' hoặc 'New York'." } }, - "openaiCompatibleLabel": "Tương thích OpenAI", - "anthropicCompatibleLabel": "Tương thích với con người", + "openaiCompatibleLabel": "Tương thích với OpenAI", + "anthropicCompatibleLabel": "Tương thích với Anthropic", "noTemplateForFormat": "Không có mẫu cho định dạng này", - "translationFailed": "Dịch không thành công: {error}", - "pipelineDebugger": "Trình gỡ lỗi đường ống", - "translationPipeline": "Đường dẫn dịch thuật", - "pipelineVisualization": "Trực quan hóa đường ống", - "pipelineVisualizationHint": "Gửi tin nhắn để xem yêu cầu của bạn diễn ra như thế nào thông qua quá trình phát hiện → dịch thuật → cuộc gọi của nhà cung cấp.", - "chatTesterDescription": "Gửi tin nhắn dưới dạng định dạng ứng dụng khách cụ thể và kiểm tra từng bước của quy trình dịch thuật.", - "chatTesterFlow": "Yêu cầu của khách hàng → Phát hiện định dạng → Trung gian OpenAI → Định dạng nhà cung cấp → Phản hồi", - "clickStepToInspect": "Nhấp vào bất kỳ bước nào để kiểm tra dữ liệu ở giai đoạn đó.", - "clientFormat": "Định dạng khách hàng", - "provider": "nhà cung cấp", - "modelPlaceholder": "Chọn hoặc nhập tên mẫu máy...", + "translationFailed": "Không thể dịch: {error}", + "pipelineDebugger": "Trình gỡ lỗi quy trình", + "translationPipeline": "Quy trình dịch thuật", + "pipelineVisualization": "Trực quan hóa quy trình", + "pipelineVisualizationHint": "Gửi tin nhắn để xem yêu cầu của bạn đi qua quá trình phát hiện → dịch thuật → gọi nhà cung cấp như thế nào.", + "chatTesterDescription": "Gửi tin nhắn theo một định dạng ứng dụng khách cụ thể và kiểm tra từng bước của quy trình dịch thuật.", + "chatTesterFlow": "Yêu cầu của ứng dụng khách → Phát hiện định dạng → Định dạng trung gian OpenAI → Định dạng nhà cung cấp → Phản hồi", + "clickStepToInspect": "Nhấp vào bất kỳ bước nào để kiểm tra dữ liệu tại giai đoạn đó.", + "clientFormat": "Định dạng ứng dụng khách", + "provider": "Nhà cung cấp", + "modelPlaceholder": "Chọn hoặc nhập tên mô hình...", "sendMessageToSeePipeline": "Gửi tin nhắn để xem quy trình dịch thuật", - "chatMessageHintPrefix": "Tin nhắn của bạn sẽ được định dạng dưới dạng", + "chatMessageHintPrefix": "Tin nhắn của bạn sẽ được định dạng thành một", "chatMessageHintSuffix": "yêu cầu, được dịch qua quy trình và gửi đến nhà cung cấp đã chọn.", "youWithFormat": "Bạn ({format})", "assistant": "Trợ lý", "typeMessage": "Nhập tin nhắn...", "send": "Gửi", - "clientRequest": "Yêu cầu của khách hàng", - "clientRequestDescription": "Nội dung yêu cầu mà khách hàng của bạn sẽ gửi nó", + "clientRequest": "Yêu cầu của ứng dụng khách", + "clientRequestDescription": "Phần thân yêu cầu do ứng dụng khách của bạn gửi", "formatDetected": "Đã phát hiện định dạng", "formatDetectedDescription": "OmniRoute tự động phát hiện định dạng API từ cấu trúc yêu cầu", - "openaiIntermediate": "Trung cấp OpenAI", - "openaiIntermediateDescription": "Tất cả các định dạng trước tiên được chuẩn hóa thành định dạng OpenAI (cầu nối phổ quát)", + "openaiIntermediate": "Định dạng trung gian OpenAI", + "openaiIntermediateDescription": "Tất cả các định dạng trước tiên đều được chuẩn hóa sang định dạng OpenAI (cầu nối vạn năng)", "providerFormat": "Định dạng nhà cung cấp", "providerFormatDescription": "Định dạng OpenAI được dịch sang định dạng gốc của nhà cung cấp", "providerResponse": "Phản hồi của nhà cung cấp", - "providerResponseRawDescription": "Phản hồi thô từ API nhà cung cấp", - "providerResponseSseDescription": "Luồng SSE thô từ API nhà cung cấp", + "providerResponseRawDescription": "Phản hồi thô từ API của nhà cung cấp", + "providerResponseSseDescription": "Luồng SSE thô từ API của nhà cung cấp", "unexpectedError": "Đã xảy ra lỗi không mong muốn", "error": "Lỗi", "errorMessage": "Lỗi: {message}", - "requestFailed": "Yêu cầu không thành công", - "noTextExtracted": "(Không trích xuất văn bản)", - "liveMonitorMemoryNote": "Các sự kiện được lưu trữ trong bộ nhớ và bị mất khi khởi động lại.", - "liveMonitorMemoryCapNote": "Tối đa 200 sự kiện được giữ lại.", + "requestFailed": "Yêu cầu thất bại", + "noTextExtracted": "(Không có văn bản nào được trích xuất)", + "liveMonitorMemoryNote": "Các sự kiện được lưu trữ trong bộ nhớ và sẽ bị mất khi khởi động lại.", + "liveMonitorMemoryCapNote": "Giữ lại tối đa 200 sự kiện.", "eventSourcesLabel": "Nguồn sự kiện:", - "eventSourceTranslatorPage": "• Trang dịch (Người kiểm tra trò chuyện, Bàn kiểm tra)", - "eventSourceMainPipeline": "• Đường dẫn yêu cầu chính (lưu lượng truy cập CLI/IDE/API)", - "liveMonitorDescriptionPrefix": "Hiển thị các sự kiện dịch khi lệnh gọi API đi qua OmniRoute. Các sự kiện đến từ bộ đệm trong bộ nhớ (đặt lại khi khởi động lại). sử dụng", - "liveMonitorDescriptionSuffix": "hoặc lệnh gọi API bên ngoài để tạo sự kiện.", - "streamTransformer": "Máy biến dòng", - "modeDescriptionStreamTransformer": "Chạy các luồng SSE hoàn thành trò chuyện thông qua biến áp Phản hồi.", - "streamTransformerTitle": "Máy biến dòng phản hồi", - "streamTransformerDescription": "Dán luồng SSE hoàn thành trò chuyện, chạy luồng đó qua biến áp Phản hồi của OmniRoute và kiểm tra các sự kiện phản hồi được phát ra trước khi kết nối với máy khách.", + "eventSourceTranslatorPage": "• Trang Trình dịch (Trình kiểm thử trò chuyện, Bàn thử nghiệm)", + "eventSourceMainPipeline": "• Quy trình xử lý yêu cầu chính (lưu lượng CLI/IDE/API)", + "liveMonitorDescriptionPrefix": "Hiển thị các sự kiện chuyển đổi khi các cuộc gọi API đi qua OmniRoute. Các sự kiện được lấy từ bộ đệm trong bộ nhớ (đặt lại khi khởi động lại). Sử dụng", + "liveMonitorDescriptionSuffix": ", hoặc các cuộc gọi API bên ngoài để tạo sự kiện.", + "streamTransformer": "Bộ chuyển đổi luồng", + "modeDescriptionStreamTransformer": "Chạy các luồng SSE chat completions qua bộ chuyển đổi Responses.", + "streamTransformerTitle": "Bộ chuyển đổi luồng Responses", + "streamTransformerDescription": "Dán một luồng SSE chat completions, chạy luồng đó qua bộ chuyển đổi Responses của OmniRoute và kiểm tra các sự kiện response.* được phát ra trước khi tích hợp vào ứng dụng khách.", "loadTextSample": "Tải mẫu văn bản", - "loadToolSample": "Tải mẫu lệnh gọi công cụ", - "transformToResponses": "Chuyển đổi thành phản hồi", - "rawChatSseInput": "Số lần hoàn thành trò chuyện thô SSE", - "transformedResponsesSse": "API phản hồi được chuyển đổi SSE", + "loadToolSample": "Tải mẫu gọi công cụ", + "transformToResponses": "Chuyển đổi sang Responses", + "rawChatSseInput": "Luồng SSE chat completions thô", + "transformedResponsesSse": "SSE API Responses đã được chuyển đổi", "noResultsYet": "Chưa có kết quả", - "transformedEvents": "Sự kiện chuyển đổi", - "uniqueEventTypes": "Các loại sự kiện độc đáo", - "inputLines": "Dòng đầu vào", - "outputLines": "Dòng đầu ra", - "transformedEventTimeline": "Dòng thời gian sự kiện được chuyển đổi", - "transformerTimelineHint": "Chạy máy biến áp để kiểm tra các sự kiện phản hồi.output_* được phát ra theo thứ tự.", + "transformedEvents": "Các sự kiện đã chuyển đổi", + "uniqueEventTypes": "Các loại sự kiện duy nhất", + "inputLines": "Các dòng đầu vào", + "outputLines": "Các dòng đầu ra", + "transformedEventTimeline": "Dòng thời gian sự kiện đã chuyển đổi", + "transformerTimelineHint": "Chạy bộ chuyển đổi để kiểm tra các sự kiện response.output_* được phát ra theo thứ tự.", "eventType": "Loại sự kiện", "eventPreview": "Xem trước", - "comboRouted": "Kết hợp được định tuyến", - "uniqueEndpoints": "Điểm cuối duy nhất", - "routeDetails": "Chi tiết tuyến đường", - "comboBadge": "kết hợp", - "routeEndpointLabel": "Điểm cuối", + "comboRouted": "Combo đã định tuyến", + "uniqueEndpoints": "Các endpoint duy nhất", + "routeDetails": "Chi tiết định tuyến", + "comboBadge": "Combo", + "routeEndpointLabel": "Endpoint", "routeConnectionLabel": "Kết nối", - "scenarioVision": "Tầm nhìn (hiểu hình ảnh)", - "scenarioSchemaCoercion": "Lược đồ cưỡng bức (đầu ra có cấu trúc)", - "techniques": "Kỹ thuật:" + "scenarioVision": "Vision (hiểu hình ảnh)", + "scenarioSchemaCoercion": "Ép kiểu lược đồ (đầu ra có cấu trúc)", + "techniques": "Kỹ thuật:", + "friendlyTitle": "Translator", + "friendlySubtitle": "Use your existing app with any provider — without rewriting code.", + "conceptHeadline": "Your app speaks one API's \"language\". The Translator converts it to use another provider.", + "conceptDiagramAppLabel": "Your app", + "conceptDiagramSourceLabel": "Source format", + "conceptDiagramHubLabel": "OpenAI (hub)", + "conceptDiagramTargetLabel": "Target provider", + "conceptDiagramExampleApp": "e.g. Anthropic SDK", + "conceptDiagramExampleSource": "claude", + "conceptDiagramExampleTarget": "Gemini", + "conceptHowItWorksToggle": "How it works", + "conceptHowItWorksBody": "Your app sends a request in its own format. The Translator detects the format, converts it through OpenAI as an intermediate hub (or directly when a direct translator is available), sends it to the chosen provider, and returns the response converted back to your app's format.", + "tabTranslate": "Translate", + "tabMonitor": "Monitor", + "tabTranslateAriaLabel": "Go to the Translate tab", + "tabMonitorAriaLabel": "Go to the Monitor tab", + "simpleAppUsesLabel": "My app uses", + "simpleAppUsesHint": "The API format your app speaks (e.g. Anthropic SDK = claude).", + "simpleSendToLabel": "Send to", + "simpleSendToHint": "Where to actually send the request (a provider connected in OmniRoute).", + "simpleStartWithLabel": "Start with", + "simpleStartWithExamplePlaceholder": "Select a ready-made example", + "simpleStartWithCustomOption": "Paste your request (advanced)", + "simpleModeLabel": "Mode", + "simpleModePreview": "Preview translation only", + "simpleModeSend": "Send and see response", + "simpleAdvancedToggle": "Advanced", + "simpleInputPanelTitle": "Input", + "simpleInputPanelHint": "Free-text message or ready-made example", + "simpleResultPanelTitle": "Translation + Response", + "narratedDetected": "✓ Detected: {format}", + "narratedTranslating": "Translating to {target}...", + "narratedSending": "Sending to {target}...", + "narratedSuccess": "→ translated to {target} · response in {latency}ms", + "narratedError": "Failed: {reason}", + "narratedSeeTranslatedJson": "see translated JSON", + "narratedSeePipeline": "see pipeline", + "advancedSectionTitle": "Advanced", + "advancedSectionSubtitle": "Raw JSON, pipeline and technical tools. Everything here is the same as the old tabs — just reorganized.", + "advancedRawJsonTitle": "Raw JSON (auto-detect + Monaco)", + "advancedRawJsonSubtitle": "Paste a JSON request; the format is detected automatically.", + "advancedPipelineTitle": "OpenAI intermediate pipeline", + "advancedPipelineSubtitle": "Visualize each translation step (hub-and-spoke).", + "advancedStreamTransformTitle": "Stream Transformer (Chat → Responses SSE)", + "advancedStreamTransformSubtitle": "Converts Chat Completions SSE into Responses API.", + "advancedTestBenchTitle": "Test Bench (8 scenarios)", + "advancedTestBenchSubtitle": "Runs all scenarios and reports pass/fail + compatibility %.", + "advancedCompressionTitle": "Compression Preview", + "advancedCompressionSubtitle": "Estimate token savings across different compression modes.", + "monitorOriginHint": "Events generated by Translate or the main pipeline appear here in real time.", + "monitorEmptyCta": "Go to the Translate tab and send a request — it will appear here.", + "monitorOpenTranslateButton": "Go to Translate", + "pipelineStepClientRequest": "Client Request", + "pipelineStepClientRequestDesc": "Request received in client format", + "pipelineStepFormatDetected": "Format Detected", + "pipelineStepFormatDetectedDesc": "Auto-detected source format", + "pipelineStepOpenAIIntermediate": "OpenAI Intermediate", + "pipelineStepOpenAIIntermediateDesc": "Translated to OpenAI hub format", + "pipelineStepProviderFormat": "Provider Format", + "pipelineStepProviderFormatDesc": "Translated to provider target format", + "pipelineStepProviderResponse": "Provider Response", + "pipelineStepProviderResponseDesc": "Streaming response from provider", + "conceptDiagramArrow1": "speaks", + "conceptDiagramArrow2": "translates", + "conceptDiagramArrow3": "converts", + "conceptDiagramExampleHub": "OpenAI", + "conceptDiagramHubTooltip": "Intermediate hub used by the translator to convert between formats that don't have a direct mapping.", + "conceptDiagramSourceTooltip": "The API format your app speaks (e.g., Anthropic SDK = claude).", + "conceptDiagramTargetTooltip": "The provider where the request will actually be sent.", + "compressionEmptyHint": "Fill in the input field on the Translate tab (Simple Controls or Raw JSON) to enable the preview.", + "compressionModeLabel": "Compression mode", + "compressionPreviewButton": "Preview Compression", + "compressionPreviewing": "Previewing…" }, "usage": { - "title": "Cách sử dụng", - "loggerTab": "Trình ghi nhật ký", - "proxyTab": "ủy nhiệm", + "title": "Mức sử dụng", + "loggerTab": "Logger", + "proxyTab": "Proxy", "budgetManagement": "Quản lý ngân sách", "budgetSaved": "Đã lưu giới hạn ngân sách", - "budgetSaveFailed": "Không thể tiết kiệm ngân sách", + "budgetSaveFailed": "Không thể lưu ngân sách", "loadingBudgetData": "Đang tải dữ liệu ngân sách...", "noApiKeysTitle": "Không có khóa API", "noApiKeysDescription": "Thêm khóa API trước để thiết lập giới hạn ngân sách.", @@ -5909,394 +6804,423 @@ "dailyLimitUsd": "Giới hạn hàng ngày (USD)", "monthlyLimitUsd": "Giới hạn hàng tháng (USD)", "warningThresholdPercent": "Ngưỡng cảnh báo (%)", - "dailyLimitPlaceholder": "ví dụ: 5 giờ 00", - "monthlyLimitPlaceholder": "ví dụ: 50,00", + "dailyLimitPlaceholder": "Ví dụ: 5.00", + "monthlyLimitPlaceholder": "Ví dụ: 50.00", "warningThresholdPlaceholder": "80", "saveLimits": "Lưu giới hạn", "budgetOk": "Ngân sách ổn — còn lại {remaining}", - "budgetExceeded": "Vượt quá ngân sách — yêu cầu có thể bị chặn", + "budgetExceeded": "Vượt quá ngân sách — các yêu cầu có thể bị chặn", "totalRequests": "Tổng số yêu cầu", "noDataYet": "Chưa có dữ liệu", "latency": "Độ trễ", "latencyP50": "p50", "latencyP95": "p95", "latencyP99": "p99", - "promptCache": "Bộ nhớ đệm nhắc nhở", + "promptCache": "Prompt Cache", "systemHealth": "Tình trạng hệ thống", - "entries": "Bài dự thi", + "entries": "Bản ghi", "activeCount": "{count} đang hoạt động", - "openCircuitBreakersDetected": "Đã phát hiện bộ ngắt mạch hở", - "hitRate": "Tỷ lệ trúng", - "hitsMisses": "Lượt truy cập / Bỏ lỡ", + "openCircuitBreakersDetected": "Đã phát hiện các bộ ngắt mạch ở trạng thái mở", + "hitRate": "Tỷ lệ trúng cache", + "hitsMisses": "Trúng cache / Trượt cache", "circuitBreakers": "Bộ ngắt mạch", "lockedIPs": "IP bị khóa", - "lockoutsAutoRefreshHint": "Khóa giới hạn tốc độ trên mỗi mô hình • Tự động làm mới 10 giây", - "lockedCount": "{count, plural, one {# locked} other {# locked}}", - "timeLeft": "{time} còn lại", - "howItWorks": "Nó hoạt động như thế nào", - "howItWorksSubtitle": "Tìm hiểu cách đánh giá xác thực phản hồi LLM của bạn", - "define": "Xác định", - "defineStepDescription": "Tạo các trường hợp thử nghiệm với lời nhắc đầu vào và tiêu chí đầu ra dự kiến bằng cách sử dụng các chiến lược như chứa, biểu thức chính quy hoặc đối sánh chính xác.", + "lockoutsAutoRefreshHint": "Khóa giới hạn tốc độ theo từng mô hình • Tự động làm mới sau 10 giây", + "lockedCount": "{count, plural, one {# bị khóa} other {# bị khóa}}", + "timeLeft": "Còn {time}", + "howItWorks": "Cách hoạt động", + "howItWorksSubtitle": "Tìm hiểu cách các đánh giá xác thực phản hồi LLM của bạn", + "define": "Định nghĩa", + "defineStepDescription": "Tạo các trường hợp kiểm thử với các prompt đầu vào và tiêu chí đầu ra dự kiến bằng cách sử dụng các chiến lược như chứa, regex hoặc khớp chính xác.", "run": "Chạy", - "runStepDescription": "Thực hiện các trường hợp kiểm thử đối với điểm cuối LLM của bạn thông qua OmniRoute. Mỗi trường hợp được gửi dưới dạng một yêu cầu API thực sự.", + "runStepDescription": "Thực thi các trường hợp kiểm thử đối với các endpoint LLM của bạn thông qua OmniRoute. Mỗi trường hợp được gửi dưới dạng một yêu cầu API thực tế.", "evaluate": "Đánh giá", - "evaluateStepDescription": "Các câu trả lời được so sánh với các tiêu chí dự kiến. Xem đạt/không đạt cho từng trường hợp với số liệu về độ trễ và phản hồi chi tiết.", - "evalsStrategyContainsLabel": "__MISSING__:Contains", - "evalsStrategyExactLabel": "__MISSING__:Exact Match", - "evalsStrategyRegexLabel": "__MISSING__:Regex", - "evalsStrategyCustomLabel": "__MISSING__:Custom Logic", - "evalsStrategyContainsDescription": "__MISSING__:Checks if the LLM output contains the expected substring.", - "evalsStrategyExactDescription": "__MISSING__:Checks if the LLM output exactly matches the expected value.", - "evalsStrategyRegexDescription": "__MISSING__:Validates the LLM output against a regular expression pattern.", - "evalsStrategyCustomDescription": "__MISSING__:Custom evaluation logic (configured via JSON).", - "historyColumnSuiteName": "__MISSING__:Suite Name", - "historyColumnTarget": "__MISSING__:Target", - "historyColumnPassRate": "__MISSING__:Pass Rate", - "historyColumnAvgLatencyMs": "__MISSING__:Avg Latency", - "historyColumnCreatedAt": "__MISSING__:Executed", - "evalSuites": "Bộ đánh giá", - "evalSuitesHint": "Nhấp vào một bộ để xem các trường hợp thử nghiệm, sau đó chạy để đánh giá điểm cuối LLM của bạn", - "evalsLoading": "Đang tải bộ đánh giá...", + "evaluateStepDescription": "Các phản hồi được so sánh với các tiêu chí dự kiến. Xem kết quả đạt/không đạt cho từng trường hợp với các số liệu về độ trễ và phản hồi chi tiết.", + "evalsStrategyContainsLabel": "Chứa", + "evalsStrategyExactLabel": "Khớp chính xác", + "evalsStrategyRegexLabel": "Regex", + "evalsStrategyCustomLabel": "Logic tùy chỉnh", + "evalsStrategyContainsDescription": "Kiểm tra xem đầu ra của LLM có chứa chuỗi con dự kiến hay không.", + "evalsStrategyExactDescription": "Kiểm tra xem đầu ra của LLM có khớp chính xác với giá trị dự kiến hay không.", + "evalsStrategyRegexDescription": "Xác thực đầu ra của LLM theo mẫu regex.", + "evalsStrategyCustomDescription": "Logic đánh giá tùy chỉnh (được cấu hình qua JSON).", + "historyColumnSuiteName": "Tên bộ kiểm thử", + "historyColumnTarget": "Mục tiêu", + "historyColumnPassRate": "Tỷ lệ đạt", + "historyColumnAvgLatencyMs": "Độ trễ trung bình", + "historyColumnCreatedAt": "Đã thực thi", + "evalSuites": "Các bộ đánh giá", + "evalSuitesHint": "Nhấp vào một bộ đánh giá để xem các trường hợp kiểm thử, sau đó chạy để đánh giá các endpoint LLM của bạn", + "evalsLoading": "Đang tải các bộ đánh giá...", "noEvalSuitesFound": "Không tìm thấy bộ đánh giá nào", - "noEvalSuitesDescription": "Bộ đánh giá có thể được xác định thông qua API hoặc bằng mã. Họ kiểm tra kết quả đầu ra của mô hình so với kết quả mong đợi bằng cách sử dụng các chiến lược như chứa, biểu thức chính quy, đối sánh chính xác và các hàm tùy chỉnh.", - "columnCase": "trường hợp", + "noEvalSuitesDescription": "Các bộ đánh giá có thể được định nghĩa qua API hoặc trong mã. Chúng kiểm tra đầu ra của mô hình so với kết quả mong đợi bằng các chiến lược như chứa, regex, khớp chính xác và các hàm tùy chỉnh.", + "columnCase": "Trường hợp", "columnStatus": "Trạng thái", "columnLatency": "Độ trễ", "columnDetails": "Chi tiết", - "columnModel": "người mẫu", + "columnModel": "Mô hình", "columnStrategy": "Chiến lược", "columnExpected": "Dự kiến", - "statsSuites": "dãy phòng", - "statsTestCases": "Trường hợp thử nghiệm", - "statsModels": "Người mẫu", - "statsCoverage": "Bảo hiểm", + "statsSuites": "Bộ đánh giá", + "statsTestCases": "Trường hợp kiểm thử", + "statsModels": "Mô hình", + "statsCoverage": "Độ bao phủ", "statsStrategiesCount": "{count} chiến lược", "evaluationStrategies": "Chiến lược đánh giá", - "modelsUnderTest": "Mô hình đang được thử nghiệm", - "searchSuitesPlaceholder": "Bộ tìm kiếm...", - "passSuffix": "vượt qua", - "casesCount": "{count, plural, one {# case} other {# cases}}", + "modelsUnderTest": "Mô hình được kiểm thử", + "searchSuitesPlaceholder": "Tìm kiếm bộ đánh giá...", + "passSuffix": "đạt", + "casesCount": "{count, plural, one {# trường hợp} other {# trường hợp}}", "runEval": "Chạy đánh giá", "runAllSuites": "Chạy tất cả", - "runAllRunning": "Chạy hết...", + "runAllRunning": "Đang chạy tất cả...", "runAllProgress": "Đang chạy {current}/{total}: {name}", - "runAllFailedSuites": "{count, plural, one {# suite failed} other {# suites failed}}", - "runAllCompleted": "Chạy {suites} bộ — {passed} đã đạt, {failed} không thành công", - "runAllCompletedWithFailures": "Chạy {completed} bộ; {failedSuites} không hoàn thành được", + "runAllFailedSuites": "{count, plural, one {# bộ thất bại} other {# bộ thất bại}}", + "runAllCompleted": "Đã chạy {suites} bộ — {passed} đạt, {failed} thất bại", + "runAllCompletedWithFailures": "Đã chạy {completed} bộ; {failedSuites} bộ không thể hoàn thành", "runningProgress": "Đang chạy {current}/{total}...", - "passRate": "tỷ lệ đậu", - "summaryBreakdown": "{passed} đã đạt · {failed} thất bại · tổng cộng {total}", + "passRate": "tỷ lệ đạt", + "summaryBreakdown": "{passed} đạt · {failed} thất bại · tổng cộng {total}", "passedIconLabel": "✅ Đạt", "failedIconLabel": "❌ Thất bại", - "resultPassed": "Đã đậu", - "resultFailed": "thất bại", + "resultPassed": "Đạt", + "resultFailed": "Thất bại", "expandResult": "Mở rộng chi tiết kết quả", "collapseResult": "Thu gọn chi tiết kết quả", "detailsContains": "Chứa: \"{term}\"", - "detailsRegex": "Biểu thức chính quy: {pattern}", - "detailsExpected": "Dự kiến: \"{expected}\"", - "expectedOutputLabel": "Sản lượng dự kiến", + "detailsRegex": "Regex: {pattern}", + "detailsExpected": "Mong đợi: \"{expected}\"", + "expectedOutputLabel": "Đầu ra mong đợi", "noResultsYet": "Chưa có kết quả", - "testCasesCount": "Các trường hợp thử nghiệm ({count})", - "noTestCasesDefined": "Không có trường hợp thử nghiệm nào được xác định", - "runEvalHint": "Nhấp vào \"Chạy đánh giá\" để thực thi tất cả các trường hợp đối với điểm cuối LLM của bạn. Mỗi bài kiểm tra sẽ gửi một yêu cầu thực sự thông qua OmniRoute.", - "notifyNoTestCases": "Không có trường hợp thử nghiệm nào được xác định cho bộ phần mềm này", - "notifyAllCasesPassed": "Tất cả {total} trường hợp đã thành công ✅", - "notifySomeCasesFailed": "{passed}/{total} đã đạt, {failed} không thành công", - "notifyEvalRunFailed": "Chạy đánh giá không thành công", + "testCasesCount": "Trường hợp kiểm thử ({count})", + "noTestCasesDefined": "Chưa có trường hợp kiểm thử nào được xác định", + "runEvalHint": "Nhấp vào \"Chạy đánh giá\" để thực thi tất cả các trường hợp kiểm thử trên endpoint LLM của bạn. Mỗi trường hợp kiểm thử sẽ gửi một yêu cầu thực tế qua OmniRoute.", + "notifyNoTestCases": "Không có trường hợp kiểm thử nào được xác định cho bộ này", + "notifyAllCasesPassed": "Cả {total} trường hợp đều đạt ✅", + "notifySomeCasesFailed": "{passed}/{total} đạt, {failed} thất bại", + "notifyEvalRunFailed": "Chạy đánh giá thất bại", "notifyEvalTitle": "Đánh giá: {name}", "modelEvals": "Đánh giá mô hình", - "evalsHeroDescription": "Kiểm tra và xác thực các điểm cuối LLM của bạn bằng cách chạy các bộ đánh giá được xác định trước. Mỗi bộ chứa các trường hợp thử nghiệm gửi lời nhắc thực sự thông qua OmniRoute và so sánh phản hồi với tiêu chí dự kiến ​​— giúp bạn phát hiện hồi quy, so sánh mô hình và đảm bảo chất lượng phản hồi giữa các nhà cung cấp.", - "qualityValidation": "Xác nhận chất lượng", + "evalsHeroDescription": "Kiểm tra và xác thực các endpoint LLM của bạn bằng cách chạy các bộ đánh giá được xác định trước. Mỗi bộ chứa các trường hợp kiểm thử gửi prompt thực tế qua OmniRoute và so sánh phản hồi với các tiêu chí mong đợi — giúp bạn phát hiện hồi quy, so sánh mô hình và đảm bảo chất lượng phản hồi giữa các nhà cung cấp.", + "qualityValidation": "Xác thực chất lượng", "modelComparison": "So sánh mô hình", "regressionDetection": "Phát hiện hồi quy", - "latencyBenchmarks": "Điểm chuẩn độ trễ", + "latencyBenchmarks": "Đánh giá chuẩn độ trễ", "modelLockouts": "Khóa mô hình", - "noLockouts": "Hiện không có mẫu nào bị khóa", - "activeSessions": "Phiên hoạt động", + "noLockouts": "Hiện không có mô hình nào bị khóa", + "activeSessions": "Các phiên đang hoạt động", "noSessions": "Không có phiên hoạt động nào", - "sessionsHint": "Phiên xuất hiện khi yêu cầu chảy qua proxy", - "sessionsTrackedHint": "Được theo dõi thông qua dấu vân tay yêu cầu • Tự động làm mới 5 giây", + "sessionsHint": "Các phiên sẽ xuất hiện khi có các yêu cầu truyền qua proxy", + "sessionsTrackedHint": "Được theo dõi qua dấu vân tay yêu cầu • Tự động làm mới mỗi 5 giây", "session": "Phiên", - "age": "Tuổi", + "age": "Thời gian tồn tại", "requests": "Yêu cầu", "connection": "Kết nối", "durationMillisecondsShort": "{value}ms", "durationSecondsShort": "{value}s", - "durationMinutesShort": "{value} phút", + "durationMinutesShort": "{value}m", "durationHoursShort": "{value}h", "reasonSeparator": "-", "notAvailableSymbol": "-", "providerLimits": "Giới hạn của nhà cung cấp", "noProviders": "Không có nhà cung cấp nào được kết nối", - "connectProvidersForQuota": "Kết nối với nhà cung cấp bằng OAuth để theo dõi giới hạn và mức sử dụng hạn ngạch API của bạn.", - "accountsCount": "{count, plural, one {# account} other {# accounts}}", + "connectProvidersForQuota": "Kết nối với các nhà cung cấp bằng OAuth để theo dõi giới hạn hạn ngạch và mức sử dụng API của bạn.", + "accountsCount": "{count, plural, one {# tài khoản} other {# tài khoản}}", "filteredFromCount": "(được lọc từ {count})", "autoRefresh": "Tự động làm mới", "refreshAll": "Làm mới tất cả", "loadingQuotas": "Đang tải...", "account": "Tài khoản", - "modelQuotas": "Hạn ngạch mẫu", - "lastUsed": "Last Refreshed", - "actions": "hành động", + "modelQuotas": "Hạn ngạch mô hình", + "lastUsed": "Lần làm mới cuối", + "actions": "Hành động", "refreshQuota": "Làm mới hạn ngạch", - "today": "hôm nay", + "today": "Hôm nay", "tomorrow": "Ngày mai", "dayTimeFormat": "{day}, {time}", - "inDuration": "trong {duration}", - "notApplicable": "không áp dụng", - "rawPlanWithValue": "Gói thô: {plan}", - "noPlanFromProvider": "Không có kế hoạch từ nhà cung cấp", + "inDuration": "sau {duration}", + "notApplicable": "N/A", + "rawPlanWithValue": "Gói gốc: {plan}", + "noPlanFromProvider": "Không có gói dịch vụ từ nhà cung cấp", "noQuotaData": "Không có dữ liệu hạn ngạch", - "cardExpand": "__MISSING__:Expand", - "cardCollapse": "__MISSING__:Collapse", - "moreQuotas": "__MISSING__:+{count} more", - "ungrouped": "Ungrouped", - "viewFlat": "Flat", - "viewByEnvironment": "By Environment", - "noQuotaDataAvailable": "Không có sẵn dữ liệu hạn ngạch", - "noAccountsForTierFilter": "Không tìm thấy tài khoản nào cho bộ lọc cấp độ", + "cardExpand": "Mở rộng", + "cardCollapse": "Thu gọn", + "moreQuotas": "+{count} khác", + "ungrouped": "Chưa phân nhóm", + "viewFlat": "Dạng phẳng", + "viewByEnvironment": "Theo môi trường", + "noQuotaDataAvailable": "Không có dữ liệu hạn ngạch", + "noAccountsForTierFilter": "Không tìm thấy tài khoản nào phù hợp với bộ lọc hạng", "tierAll": "Tất cả", "tierEnterprise": "Doanh nghiệp", - "tierTeam": "đội", + "tierTeam": "Nhóm", "tierBusiness": "Kinh doanh", - "tierUltra": "siêu", - "tierPro": "chuyên nghiệp", - "tierPlus": "Cộng thêm", - "tierFree": "miễn phí", - "tierLite": "__MISSING__:Lite", + "tierUltra": "Ultra", + "tierPro": "Pro", + "tierPlus": "Plus", + "tierFree": "Miễn phí", + "tierLite": "Lite", "tierUnknown": "Không xác định", - "statTotal": "__MISSING__:Total", - "statCritical": "__MISSING__:Critical", - "statAlert": "__MISSING__:Alert", - "statHealthy": "__MISSING__:Healthy", - "filterPurchaseTypeLabel": "__MISSING__:Type", - "filterTierLabel": "__MISSING__:Tier", - "purchaseAll": "__MISSING__:All", - "purchaseOauthSub": "__MISSING__:Subscription", - "purchaseOauthFree": "__MISSING__:OAuth Free", - "purchaseApiKey": "__MISSING__:API Key", - "creditsLabel": "__MISSING__:Credits", - "creditBalanceHint": "__MISSING__:Remaining balance", - "unlimitedLabel": "__MISSING__:Unlimited", - "refreshing": "__MISSING__:Refreshing", - "resetsIn": "__MISSING__:Resets in", - "editCutoffs": "Chỉnh sửa điểm cắt", - "forceRefresh": "Làm mới ngay bây giờ", - "suiteBuilderSaveFailed": "Failed to save suite", - "clone": "bản sao", - "exportSuite": "Xuất khẩu", - "importSuite": "Nhập khẩu", - "suiteExported": "Đã xuất bộ phần mềm", - "suiteExportFailed": "Không xuất được bộ phần mềm", - "suiteImportReady": "Đã tải bộ dữ liệu nhập để xem xét", - "suiteImportFailed": "Không thể nhập bộ phần mềm", - "suiteImportInvalid": "Bộ đánh giá JSON không hợp lệ", - "suiteBuilderCloneSuffix": "sao chép", - "suiteBuilderImportedSuite": "Bộ nhập khẩu", - "scorecardTitle": "Scorecard", - "evalApiKey": "API Key", - "scorecardPassRate": "Pass Rate", - "targetTypeModel": "Model", - "actualOutputLabel": "Actual Output", - "evalTargetHint": "Select a model or combo to evaluate.", - "suiteBuilderDeleted": "Suite deleted successfully", - "suiteBuilderCaseCardHint": "Define the input prompt and expected output criteria.", - "nextResetUtc": "Next reset (UTC)", - "scorecardHint": "Aggregated pass rates across all evaluation suites.", - "suiteLatestRunsHint": "Most recent evaluation runs for this suite.", - "saving": "Saving", - "suiteBuilderCaseModelLabel": "Model (optional)", - "evalControlsTitle": "Evaluation Controls", - "suiteBuilderEditTitle": "Edit Eval Suite", - "suiteBuilderCaseStrategyLabel": "Validation Strategy", - "notifySelectDifferentCompareTarget": "Please select a different target for comparison", - "recentRunsHint": "Showing the most recent evaluation runs. Click a run to see detailed results.", - "evalCompareHint": "Optionally compare results against a second target.", - "suiteBuilderCaseInvalid": "This case has validation errors. Please fix before saving.", - "historyEmpty": "No evaluation history yet", - "suiteBuilderUpdated": "Suite updated successfully", - "resetInterval": "Reset Interval", - "suiteBuilderCreateTitle": "Create Eval Suite", - "activePeriodSpend": "Active Period Spend", - "evalApiKeyHint": "Select which API key to use for evaluation requests.", - "evalCompareOptional": "Compare (optional)", - "suiteBuilderDeleteFailed": "Failed to delete suite", - "suiteBuilderCaseSystemPromptPlaceholder": "Optional system instructions...", - "scorecardCases": "Cases", - "runCompletedWithScore": "Evaluation completed — {score}% pass rate", - "suiteBuilderCustomBadge": "Custom", - "targetSuiteDefaults": "Suite defaults", - "suiteBuilderDeleteConfirm": "Are you sure you want to delete this suite? This action cannot be undone.", - "suiteBuilderNameLabel": "Suite Name", - "scorecardSuites": "Suites", - "evalCompareTarget": "Compare Target", - "suiteBuilderCaseModelPlaceholder": "e.g. gpt-4o-mini", - "evalControlsHint": "Configure your evaluation target and API key, then run suites to validate model quality.", - "recentRunsTitle": "Recent Runs", - "suiteBuilderCaseSystemPromptLabel": "System Prompt", - "suiteBuilderCaseExpectedPlaceholder": "e.g. def fibonacci", - "suiteBuilderCaseExpectedPlaceholderContains": "ví dụ: fibonacci chắc chắn", - "suiteBuilderCaseExpectedPlaceholderExact": "Dán phản hồi chính xác dự kiến", - "suiteBuilderCaseExpectedPlaceholderRegex": "ví dụ: ^\\\\s*\\\\{.*\\\\}\\\\s*$", - "suiteBuilderCaseExpectedHintRegex": "Sử dụng biểu thức chính quy JavaScript mà không bao gồm dấu gạch chéo.", - "suiteBuilderNamePlaceholder": "e.g. Coding Quality Suite", - "suiteBuilderAddCase": "Add Case", - "cancel": "Cancel", - "evalTarget": "Target", - "suiteBuilderCaseNameLabel": "Case Name", - "weeklyLimitUsd": "Weekly Limit (USD)", - "suiteBuilderCaseUserPromptPlaceholder": "e.g. Write a fibonacci function in Python", - "suiteBuilderNameRequired": "Suite name is required", - "suiteBuilderCaseUserPromptLabel": "User Prompt", - "daily": "Daily", - "resultErrorLabel": "Error", - "suiteBuilderBuiltInBadge": "Built-in", - "suiteBuilderCaseCardTitle": "Test Case", - "suiteBuilderDuplicateCase": "trùng lặp", - "weeklyLimitPlaceholder": "e.g. 50.00", - "suiteBuilderCaseTagsHint": "Comma-separated tags for organizing test cases.", - "notifyEvalRunFailedWithReason": "Evaluation failed: {reason}", - "weekly": "Weekly", - "runEvalRunning": "Running evaluation...", - "delete": "Delete", - "resetTimeUtc": "Reset Time (UTC)", - "evalApiKeyAuto": "Auto (use default)", - "suiteBuilderDescriptionPlaceholder": "Optional description of what this suite tests...", - "targetComparisonTitle": "Target Comparison", - "save": "Save", - "suiteBuilderCreated": "Suite created successfully", - "suiteLatestRuns": "Latest Runs", - "suiteBuilderCaseExpectedLabel": "Expected Value", - "historyLatency": "Latency", - "suiteBuilderCaseTagsPlaceholder": "e.g. coding, python", + "statTotal": "Tổng cộng", + "statCritical": "Nghiêm trọng", + "statAlert": "Cảnh báo", + "statHealthy": "Hoạt động tốt", + "filterPurchaseTypeLabel": "Loại", + "filterTierLabel": "Hạng", + "purchaseAll": "Tất cả", + "purchaseOauthSub": "Gói đăng ký", + "purchaseOauthFree": "OAuth miễn phí", + "purchaseApiKey": "Khóa API", + "creditsLabel": "Tín dụng", + "creditBalanceHint": "Số dư còn lại", + "unlimitedLabel": "Không giới hạn", + "refreshing": "Đang làm mới", + "resetsIn": "Đặt lại sau", + "editCutoffs": "Chỉnh sửa ngưỡng", + "forceRefresh": "Làm mới ngay", + "suiteBuilderSaveFailed": "Không thể lưu bộ đánh giá", + "clone": "Nhân bản", + "exportSuite": "Xuất", + "importSuite": "Nhập", + "suiteExported": "Đã xuất bộ đánh giá", + "suiteExportFailed": "Không thể xuất bộ đánh giá", + "suiteImportReady": "Đã tải bộ đánh giá đã nhập để xem xét", + "suiteImportFailed": "Không thể nhập bộ đánh giá", + "suiteImportInvalid": "JSON bộ đánh giá không hợp lệ", + "suiteBuilderCloneSuffix": "bản sao", + "suiteBuilderImportedSuite": "Bộ đánh giá đã nhập", + "scorecardTitle": "Bảng điểm", + "evalApiKey": "Khóa API", + "scorecardPassRate": "Tỷ lệ đạt", + "targetTypeModel": "Mô hình", + "actualOutputLabel": "Đầu ra thực tế", + "evalTargetHint": "Chọn một mô hình hoặc sự kết hợp để đánh giá.", + "suiteBuilderDeleted": "Đã xóa bộ đánh giá thành công", + "suiteBuilderCaseCardHint": "Xác định prompt đầu vào và tiêu chí đầu ra mong đợi.", + "nextResetUtc": "Lần đặt lại tiếp theo (UTC)", + "scorecardHint": "Tỷ lệ đạt tổng hợp trên tất cả các bộ đánh giá.", + "suiteLatestRunsHint": "Các lượt chạy đánh giá gần đây nhất cho bộ đánh giá này.", + "saving": "Đang lưu", + "suiteBuilderCaseModelLabel": "Mô hình (tùy chọn)", + "evalControlsTitle": "Kiểm soát đánh giá", + "suiteBuilderEditTitle": "Chỉnh sửa bộ đánh giá", + "suiteBuilderCaseStrategyLabel": "Chiến lược xác thực", + "notifySelectDifferentCompareTarget": "Vui lòng chọn một mục tiêu khác để so sánh", + "recentRunsHint": "Hiển thị các lượt chạy đánh giá gần đây nhất. Nhấp vào một lượt chạy để xem kết quả chi tiết.", + "evalCompareHint": "So sánh kết quả với mục tiêu thứ hai (tùy chọn).", + "suiteBuilderCaseInvalid": "Trường hợp này có lỗi xác thực. Vui lòng sửa trước khi lưu.", + "historyEmpty": "Chưa có lịch sử đánh giá", + "suiteBuilderUpdated": "Đã cập nhật bộ đánh giá thành công", + "resetInterval": "Chu kỳ đặt lại", + "suiteBuilderCreateTitle": "Tạo bộ đánh giá", + "activePeriodSpend": "Chi tiêu trong chu kỳ hiện tại", + "evalApiKeyHint": "Chọn khóa API để sử dụng cho các yêu cầu đánh giá.", + "evalCompareOptional": "So sánh (tùy chọn)", + "suiteBuilderDeleteFailed": "Không thể xóa bộ đánh giá", + "suiteBuilderCaseSystemPromptPlaceholder": "Hướng dẫn hệ thống (tùy chọn)...", + "scorecardCases": "Ca kiểm thử", + "runCompletedWithScore": "Đã hoàn thành đánh giá — tỷ lệ đạt {score}%", + "suiteBuilderCustomBadge": "Tùy chỉnh", + "targetSuiteDefaults": "Mặc định của bộ đánh giá", + "suiteBuilderDeleteConfirm": "Bạn có chắc chắn muốn xóa bộ kiểm thử này không? Hành động này không thể hoàn tác.", + "suiteBuilderNameLabel": "Tên bộ kiểm thử", + "scorecardSuites": "Các bộ kiểm thử", + "evalCompareTarget": "Mục tiêu so sánh", + "suiteBuilderCaseModelPlaceholder": "Ví dụ: gpt-4o-mini", + "evalControlsHint": "Cấu hình mục tiêu đánh giá và khóa API, sau đó chạy các bộ kiểm thử để đánh giá chất lượng mô hình.", + "recentRunsTitle": "Các lượt chạy gần đây", + "suiteBuilderCaseSystemPromptLabel": "Prompt hệ thống", + "suiteBuilderCaseExpectedPlaceholder": "Ví dụ: def fibonacci", + "suiteBuilderCaseExpectedPlaceholderContains": "Ví dụ: def fibonacci", + "suiteBuilderCaseExpectedPlaceholderExact": "Dán chính xác phản hồi dự kiến", + "suiteBuilderCaseExpectedPlaceholderRegex": "Ví dụ: ^\\\\s*\\\\{.*\\\\}\\\\s*$", + "suiteBuilderCaseExpectedHintRegex": "Sử dụng biểu thức chính quy JavaScript mà không có các dấu gạch chéo bao quanh.", + "suiteBuilderNamePlaceholder": "Ví dụ: Coding Quality Suite", + "suiteBuilderAddCase": "Thêm trường hợp kiểm thử", + "cancel": "Hủy", + "evalTarget": "Mục tiêu", + "suiteBuilderCaseNameLabel": "Tên trường hợp kiểm thử", + "weeklyLimitUsd": "Hạn mức hàng tuần (USD)", + "suiteBuilderCaseUserPromptPlaceholder": "Ví dụ: Viết một hàm fibonacci bằng Python", + "suiteBuilderNameRequired": "Tên bộ kiểm thử là bắt buộc", + "suiteBuilderCaseUserPromptLabel": "Prompt của người dùng", + "daily": "Hàng ngày", + "resultErrorLabel": "Lỗi", + "suiteBuilderBuiltInBadge": "Tích hợp sẵn", + "suiteBuilderCaseCardTitle": "Trường hợp kiểm thử", + "suiteBuilderDuplicateCase": "Nhân bản", + "weeklyLimitPlaceholder": "Ví dụ: 50.00", + "suiteBuilderCaseTagsHint": "Các thẻ được phân tách bằng dấu phẩy để sắp xếp các trường hợp kiểm thử.", + "notifyEvalRunFailedWithReason": "Đánh giá thất bại: {reason}", + "weekly": "Hàng tuần", + "runEvalRunning": "Đang chạy đánh giá...", + "delete": "Xóa", + "resetTimeUtc": "Thời gian thiết lập lại (UTC)", + "evalApiKeyAuto": "Tự động (sử dụng mặc định)", + "suiteBuilderDescriptionPlaceholder": "Mô tả tùy chọn về nội dung mà bộ kiểm thử này kiểm tra...", + "targetComparisonTitle": "So sánh mục tiêu", + "save": "Lưu", + "suiteBuilderCreated": "Đã tạo bộ kiểm thử thành công", + "suiteLatestRuns": "Các lượt chạy mới nhất", + "suiteBuilderCaseExpectedLabel": "Giá trị kỳ vọng", + "historyLatency": "Độ trễ", + "suiteBuilderCaseTagsPlaceholder": "Ví dụ: coding, python", "targetTypeCombo": "Combo", - "scorecardPassed": "Passed", - "suiteBuilderCaseTagsLabel": "Tags", - "suiteBuilderNewSuite": "New Suite", - "notifyEvalLoadFailed": "Failed to load evaluation data", - "notConfigured": "Not Configured", - "suiteBuilderCaseNamePlaceholder": "e.g. Python fibonacci test", - "intervalLabel": "Interval", - "suiteBuilderCreateAction": "Create Suite", - "suiteBuilderCasesHint": "Each case sends a prompt and validates the response.", - "suiteBuilderUpdatedAt": "Updated", - "errorBadge": "Error", - "suiteBuilderCasesTitle": "Test Cases", - "edit": "Edit", - "monthly": "Monthly", - "suiteBuilderCasesRequired": "At least one test case is required", - "weeklyLimitSummary": "Weekly budget limit summary", - "suiteBuilderDescriptionLabel": "Description", - "targetComparisonHint": "Side-by-side comparison of evaluation results between targets.", - "compareCompletedWithScore": "Comparison completed — {score}% pass rate", - "staleQuotaTooltip": "Last refresh failed — showing cached data", - "quotaThresholdLabel": "Tối thiểu còn lại", - "quotaCutoffsColumnHelp": "Dừng yêu cầu khi hạn ngạch còn lại giảm xuống tỷ lệ phần trăm này hoặc thấp hơn.", + "scorecardPassed": "Đã đạt", + "suiteBuilderCaseTagsLabel": "Thẻ", + "suiteBuilderNewSuite": "Bộ kiểm thử mới", + "notifyEvalLoadFailed": "Không tải được dữ liệu đánh giá", + "notConfigured": "Chưa cấu hình", + "suiteBuilderCaseNamePlaceholder": "Ví dụ: kiểm thử fibonacci bằng Python", + "intervalLabel": "Khoảng thời gian", + "suiteBuilderCreateAction": "Tạo bộ kiểm thử", + "suiteBuilderCasesHint": "Mỗi trường hợp kiểm thử sẽ gửi một prompt và kiểm tra phản hồi.", + "suiteBuilderUpdatedAt": "Đã cập nhật", + "errorBadge": "Lỗi", + "suiteBuilderCasesTitle": "Các trường hợp kiểm thử", + "edit": "Chỉnh sửa", + "monthly": "Hàng tháng", + "suiteBuilderCasesRequired": "Cần có ít nhất một trường hợp kiểm thử", + "weeklyLimitSummary": "Tóm tắt hạn mức ngân sách hàng tuần", + "suiteBuilderDescriptionLabel": "Mô tả", + "targetComparisonHint": "So sánh song song các kết quả đánh giá giữa các mục tiêu.", + "compareCompletedWithScore": "Đã hoàn thành so sánh — tỷ lệ đạt {score}%", + "staleQuotaTooltip": "Lần làm mới cuối cùng thất bại — đang hiển thị dữ liệu được lưu trong cache", + "quotaThresholdLabel": "Còn lại tối thiểu", + "quotaCutoffsColumnHelp": "Dừng các yêu cầu khi hạn ngạch còn lại giảm xuống tỷ lệ phần trăm này hoặc thấp hơn.", "quotaCutoffsButtonDefault": "Mặc định", - "quotaCutoffsButtonHelp": "Chỉnh sửa giới hạn hạn ngạch còn lại tối thiểu cho tài khoản này.", - "quotaCutoffsButtonDisabled": "Chưa có khoảng thời gian hạn ngạch nào dành cho tài khoản này.", + "quotaCutoffsButtonHelp": "Chỉnh sửa các giới hạn hạn ngạch còn lại tối thiểu cho tài khoản này.", + "quotaCutoffsButtonDisabled": "Chưa có khoảng thời gian hạn ngạch nào khả dụng cho tài khoản này.", "quotaCutoffsTitle": "Giới hạn hạn ngạch cho {name} ({provider})", - "quotaCutoffsExplainer": "Ghi đè phần trăm hạn ngạch còn lại tối thiểu khi tài khoản này ngừng được chọn cho mỗi khoảng thời gian hạn ngạch. Để trống để kế thừa mặc định của nhà cung cấp.", - "quotaCutoffsDefaultHint": "Số phút còn lại mặc định: {default}%", + "quotaCutoffsExplainer": "Ghi đè phần trăm hạn ngạch còn lại tối thiểu mà tại đó tài khoản này ngừng được chọn cho mỗi khoảng thời gian hạn ngạch. Để trống để kế thừa mặc định của nhà cung cấp.", + "quotaCutoffsDefaultHint": "Hạn ngạch còn lại tối thiểu mặc định: {default}%", "quotaCutoffsResetAll": "Đặt lại tất cả", - "quotaCutoffsNoWindows": "Chưa có khoảng thời gian hạn ngạch nào dành cho tài khoản này.", + "quotaCutoffsNoWindows": "Chưa có khoảng thời gian hạn ngạch nào khả dụng cho tài khoản này.", "quotaThresholdInvalid": "Nhập một số nguyên từ 0 đến 100.", - "budgetKpiToday": "hôm nay", + "budgetKpiToday": "Hôm nay", "budgetKpiThisMonth": "Tháng này", - "budgetKpiProjEom": "Dự án EOM", + "budgetKpiProjEom": "Dự kiến cuối tháng", "budgetKpiBlocked": "Bị chặn", - "budgetKpiAtRisk": "Có nguy cơ", - "budgetKpiActiveKeys": "Phím hoạt động", - "budgetSearchKeysPlaceholder": "Phím tìm kiếm...", - "budgetSortPctUsed": "Sắp xếp: % Đã sử dụng ↓", - "budgetSortTodayDollar": "Sắp xếp: Hôm nay $ ↓", - "budgetSortMonthDollar": "Sắp xếp: Tháng $ ↓", + "budgetKpiAtRisk": "Có rủi ro", + "budgetKpiActiveKeys": "Khóa hoạt động", + "budgetSearchKeysPlaceholder": "Tìm kiếm khóa...", + "budgetSortPctUsed": "Sắp xếp: % đã dùng ↓", + "budgetSortTodayDollar": "Sắp xếp: $ hôm nay ↓", + "budgetSortMonthDollar": "Sắp xếp: $ tháng này ↓", "budgetSortNameAZ": "Sắp xếp: Tên (A–Z)", - "budgetColDailyLim": "lim hàng ngày", - "budgetColMonthlyLim": "Lim hàng tháng", - "budgetColUsedPct": "% đã sử dụng", + "budgetColDailyLim": "Hạn mức hằng ngày", + "budgetColMonthlyLim": "Hạn mức hằng tháng", + "budgetColUsedPct": "% đã dùng", "budgetLoading": "Đang tải…", - "budgetNoKeysMatch": "Không có phím nào phù hợp với bộ lọc", + "budgetNoKeysMatch": "Không có khóa nào khớp với bộ lọc", "budgetLinearExtrapolation": "ngoại suy tuyến tính", - "budgetThisMonthSoFar": "Tháng này cho đến nay", + "budgetThisMonthSoFar": "Tính đến hiện tại trong tháng này", "budgetProjectedEndOfMonth": "Dự kiến cuối tháng", - "budgetByProvider": "bởi nhà cung cấp", - "budgetDailyDollar": "$ hàng ngày", - "budgetWeeklyDollar": "$ hàng tuần", - "budgetMonthlyDollar": "$ hàng tháng", + "budgetByProvider": "theo nhà cung cấp", + "budgetDailyDollar": "$ hằng ngày", + "budgetWeeklyDollar": "$ hằng tuần", + "budgetMonthlyDollar": "$ hằng tháng", "budgetWarnAtPct": "Cảnh báo ở mức %", "quotaAlerts": "Cảnh báo hạn ngạch", - "quotaTableRefreshing": "⟳ Sảng khoái...", - "noSpendLast30Days": "Không chi tiêu trong 30 ngày qua", - "updatedShort": "__MISSING__:Updated", - "lastRefreshed": "__MISSING__:Last refreshed", - "providerQuota": "__MISSING__:Provider Quota", - "providerQuotaHomeHint": "__MISSING__:Live status across connected accounts" + "quotaTableRefreshing": "⟳ Đang làm mới...", + "noSpendLast30Days": "Không phát sinh chi tiêu trong 30 ngày qua", + "updatedShort": "Đã cập nhật", + "lastRefreshed": "Cập nhật lần cuối", + "providerQuota": "Hạn ngạch nhà cung cấp", + "providerQuotaHomeHint": "Trạng thái theo thời gian thực của các tài khoản đã kết nối", + "showMoreQuotas": "Show {count} more", + "showLessQuotas": "Show less", + "tokenExpiresIn": "Token expires in {time}", + "tokenExpired": "Token expired", + "resetCreditsLabel": "Reset credits", + "redeemResetCredit": "Redeem reset", + "manageResetCredits": "View credits", + "viewResetCredits": "View reset credits", + "resetCreditsModalTitle": "Codex reset credits", + "resetCreditsModalExplainer": "Credits are ordered by expiration. Automatic redemption always uses the credit that expires first.", + "resetCreditsLoadFailed": "Failed to load reset credits", + "resetCreditsDetailsUnavailable": "Credit details are currently unavailable. Refresh and try again.", + "noResetCreditsAvailable": "No reset credits are available.", + "resetCreditDefaultTitle": "Full reset", + "resetCreditExpiresFirst": "Expires first", + "resetCreditExpiresAt": "Expires {date}", + "resetCreditNoExpiry": "No expiration date", + "redeemThisResetCredit": "Redeem", + "confirmRedeemResetCreditTitle": "Redeem this reset credit?", + "confirmRedeemResetCredit": "Redeeming immediately resets the eligible Codex usage windows and permanently consumes this credit.", + "confirmRedeemResetCreditButton": "Redeem credit", + "resetCreditRedeemed": "Reset redeemed", + "resetCreditRedeemFailed": "Failed to redeem reset credit", + "deactivateAccount": "Deactivate account (stop routing)", + "activateAccount": "Activate account (resume routing)", + "accountActivated": "Account activated", + "accountDeactivated": "Account deactivated", + "toggleActiveFailed": "Failed to update account status", + "percentUsed": "{pct}% used" }, "modals": { - "waitingAuth": "Đang chờ cấp phép", + "waitingAuth": "Đang chờ ủy quyền", "verificationUrl": "URL xác minh", "yourCode": "Mã của bạn", "remoteAccess": "Truy cập từ xa:", - "connectedSuccess": "Đã kết nối thành công!", - "connectionFailed": "Kết nối không thành công", + "connectedSuccess": "Kết nối thành công!", + "connectionFailed": "Kết nối thất bại", "chooseAuthMethod": "Chọn phương thức xác thực của bạn:", - "awsBuilderId": "ID trình tạo AWS", - "awsIamIdentity": "Trung tâm nhận dạng AWS IAM", + "awsBuilderId": "AWS Builder ID", + "awsIamIdentity": "AWS IAM Identity Center", "googleAccount": "Tài khoản Google", "githubAccount": "Tài khoản GitHub", - "importToken": "Nhập mã thông báo", - "pasteToken": "Dán mã thông báo làm mới từ Kiro IDE.", + "importToken": "Nhập token", + "pasteToken": "Dán token làm mới từ Kiro IDE.", "awsRegion": "Khu vực AWS", - "autoDetecting": "Tự động phát hiện mã thông báo...", - "readingFromCache": "Đọc từ bộ đệm AWS SSO", - "readingFromCursor": "Đọc từ cơ sở dữ liệu Cursor IDE", + "autoDetecting": "Đang tự động phát hiện token...", + "readingFromCache": "Đang đọc từ cache AWS SSO", + "readingFromCursor": "Đang đọc từ cơ sở dữ liệu Cursor IDE", "initializing": "Đang khởi tạo...", "pricingConfig": "Cấu hình giá", "loadingPricing": "Đang tải dữ liệu giá...", - "pricingRatesFormat": "Định dạng giá cước", - "noPricingData": "Không có dữ liệu giá cả", + "pricingRatesFormat": "Định dạng mức giá", + "noPricingData": "Không có dữ liệu giá", "noModelsFound": "Không tìm thấy mô hình nào" }, "loggers": { "allProviders": "Tất cả nhà cung cấp", - "allModels": "Tất cả các mẫu", + "allModels": "Tất cả mô hình", "allAccounts": "Tất cả tài khoản", - "allApiKeys": "Tất cả các khóa API", + "allApiKeys": "Tất cả khóa API", "allTypes": "Tất cả các loại", - "allLevels": "Tất cả các cấp độ", + "allLevels": "Tất cả cấp độ", "modelAZ": "Mô hình A-Z", - "modelZA": "Model Z-A", + "modelZA": "Mô hình Z-A", "loadingLogs": "Đang tải nhật ký...", "loadingProxyLogs": "Đang tải nhật ký proxy...", "noLogEntries": "Không tìm thấy mục nhật ký nào", - "noPayloadData": "Không có dữ liệu tải trọng cho mục nhập nhật ký này.", - "proxyEvent": "Sự kiện ủy quyền", - "proxy": "ủy nhiệm", + "noPayloadData": "Không có dữ liệu payload cho mục nhật ký này.", + "proxyEvent": "Sự kiện proxy", + "proxy": "Proxy", "level": "Cấp độ", "directNative": "Trực tiếp (gốc)", - "combo": "kết hợp", - "inputTokens": "Tôi:", - "outputTokens": "Ồ:" + "combo": "Combo", + "inputTokens": "I:", + "outputTokens": "O:" }, "stats": { - "usageOverview": "Tổng quan về cách sử dụng", - "outputTokens": "Mã thông báo đầu ra", + "usageOverview": "Tổng quan mức sử dụng", + "outputTokens": "Token đầu ra", "totalCost": "Tổng chi phí", - "usageByModel": "Cách sử dụng theo mẫu", + "usageByModel": "Mức sử dụng theo mô hình", "usageByAccount": "Mức sử dụng theo tài khoản", - "failedToLoad": "Không tải được số liệu thống kê sử dụng.", - "tokenHealth": "Tình trạng mã thông báo", - "totalOAuth": "Tổng OAuth", - "healthy": "khỏe mạnh", + "failedToLoad": "Không thể tải số liệu thống kê mức sử dụng.", + "tokenHealth": "Trạng thái token", + "totalOAuth": "Tổng số OAuth", + "healthy": "Hoạt động tốt", "warning": "Cảnh báo", - "errored": "Đã xảy ra lỗi", - "lastCheck": "Kiểm tra lần cuối", + "errored": "Bị lỗi", + "lastCheck": "Lần kiểm tra cuối", "noData": "Không có dữ liệu", "share": "Chia sẻ", - "unableToLoad": "Không thể tải số liệu hệ thống", - "product": "sản phẩm", + "unableToLoad": "Không thể tải các chỉ số hệ thống", + "product": "Sản phẩm", "resources": "Tài nguyên", "company": "Công ty" }, @@ -6307,144 +7231,144 @@ "password": "Mật khẩu", "unifiedProxy": "Proxy API AI hợp nhất", "unifiedAiApiProxy": "Proxy API AI hợp nhất", - "unifiedAiApiProxyDesc": "Định tuyến các yêu cầu đến nhiều nhà cung cấp AI thông qua một điểm cuối duy nhất. Cân bằng tải, chuyển đổi dự phòng và theo dõi sử dụng được tích hợp sẵn.", - "passwordNotEnabled": "Bảo vệ mật khẩu không được kích hoạt", + "unifiedAiApiProxyDesc": "Định tuyến các yêu cầu đến nhiều nhà cung cấp AI thông qua một endpoint duy nhất. Cân bằng tải, dự phòng và theo dõi mức sử dụng được tích hợp sẵn.", + "passwordNotEnabled": "Bảo vệ mật khẩu chưa được kích hoạt", "loading": "Đang tải...", "invalidPassword": "Mật khẩu không hợp lệ", "errorOccurredRetry": "Đã xảy ra lỗi. Vui lòng thử lại.", "configureInstance": "Hãy cấu hình phiên bản OmniRoute của bạn", - "runOnboardingWizard": "Chạy trình hướng dẫn tích hợp để thiết lập mật khẩu và kết nối với nhà cung cấp AI đầu tiên của bạn.", - "startOnboarding": "Bắt đầu giới thiệu", + "runOnboardingWizard": "Chạy trình hướng dẫn thiết lập ban đầu để cài đặt mật khẩu và kết nối với nhà cung cấp AI đầu tiên của bạn.", + "startOnboarding": "Bắt đầu thiết lập", "secureYourInstance": "Bảo mật phiên bản của bạn", - "setPasswordDescription": "Đặt mật khẩu để bảo vệ bảng thông tin và bảo mật các điểm cuối API của bạn khỏi bị truy cập trái phép.", - "configurePassword": "Định cấu hình mật khẩu", + "setPasswordDescription": "Đặt mật khẩu để bảo vệ bảng điều khiển và bảo mật các endpoint API của bạn khỏi truy cập trái phép.", + "configurePassword": "Cấu hình mật khẩu", "continue": "Tiếp tục", - "windowWillClose": "Cửa sổ này sẽ tự động đóng lại...", - "closeTabNow": "Bạn có thể đóng tab này ngay bây giờ.", + "windowWillClose": "Cửa sổ này sẽ tự động đóng...", + "closeTabNow": "Bạn có thể đóng tab này bây giờ.", "copyUrlManual": "Vui lòng sao chép URL từ thanh địa chỉ và dán vào ứng dụng.", - "accessDeniedDescription": "Bạn không có quyền truy cập tài nguyên này. Kiểm tra khóa API của bạn hoặc liên hệ với quản trị viên.", - "goToDashboard": "Đi tới Trang tổng quan", - "featureMultiProviderTitle": "Đa nhà cung cấp", - "featureMultiProviderDesc": "OpenAI, Anthropic, Google, v.v.", + "accessDeniedDescription": "Bạn không có quyền truy cập tài nguyên này. Vui lòng kiểm tra khóa API của bạn hoặc liên hệ với quản trị viên.", + "goToDashboard": "Đi tới bảng điều khiển", + "featureMultiProviderTitle": "Nhiều nhà cung cấp", + "featureMultiProviderDesc": "OpenAI, Anthropic, Google và nhiều nhà cung cấp khác", "featureLoadBalancingTitle": "Cân bằng tải", - "featureLoadBalancingDesc": "Phân phối yêu cầu một cách thông minh", - "featureUsageTrackingTitle": "Theo dõi sử dụng", - "featureUsageTrackingDesc": "Theo dõi chi phí và mã thông báo", + "featureLoadBalancingDesc": "Phân phối các yêu cầu một cách thông minh", + "featureUsageTrackingTitle": "Theo dõi mức sử dụng", + "featureUsageTrackingDesc": "Theo dõi chi phí và token", "resetPassword": "Đặt lại mật khẩu", - "resetDescription": "Chọn một phương pháp để khôi phục quyền truy cập vào trang tổng quan của bạn", + "resetDescription": "Chọn một phương pháp để khôi phục quyền truy cập vào bảng điều khiển của bạn", "stopServer": "Dừng máy chủ OmniRoute", "processing": "Đang xử lý...", - "pleaseWait": "Vui lòng đợi trong khi chúng tôi hoàn tất việc ủy quyền.", - "authSuccess": "Ủy quyền thành công!", + "pleaseWait": "Vui lòng chờ trong khi chúng tôi hoàn tất việc ủy quyền.", + "authSuccess": "Cấp quyền thành công!", "copyUrl": "Sao chép URL này", "accessDenied": "Truy cập bị từ chối", - "methodCliTitle": "Phương pháp 1: Đặt lại CLI", - "methodCliDescription": "Chạy lệnh sau trên máy chủ nơi OmniRoute đang chạy:", - "methodCliHint": "Điều này sẽ nhắc bạn đặt mật khẩu mới. Máy chủ phải được dừng trước tiên.", - "methodManualTitle": "Phương pháp 2: Đặt lại thủ công", - "methodManualDescription": "Xóa mật khẩu khỏi cơ sở dữ liệu và đặt mật khẩu mới khi khởi động:", - "setPasswordInYour": "Đặt mật khẩu mới trong", + "methodCliTitle": "Cách 1: Đặt lại qua CLI", + "methodCliDescription": "Chạy lệnh sau trên máy chủ mà OmniRoute đang chạy:", + "methodCliHint": "Thao tác này sẽ yêu cầu bạn thiết lập mật khẩu mới. Máy chủ phải được dừng trước tiên.", + "methodManualTitle": "Cách 2: Đặt lại thủ công", + "methodManualDescription": "Xóa mật khẩu khỏi cơ sở dữ liệu và thiết lập mật khẩu mới khi khởi động:", + "setPasswordInYour": "Đặt mật khẩu mới trong tệp của bạn", "fileLabelSuffix": "tập tin:", "newPasswordPlaceholder": "your_new_password", "deleteSettingsFile": "Xóa", - "orRemovePasswordHashField": "hoặc xóa trường mật khẩuHash", - "restartServerWithNewPassword": "Khởi động lại máy chủ - nó sẽ sử dụng mật khẩu mới", - "backToLogin": "Quay lại đăng nhập", + "orRemovePasswordHashField": "hoặc xóa trường passwordHash", + "restartServerWithNewPassword": "Khởi động lại máy chủ - máy chủ sẽ sử dụng mật khẩu mới", + "backToLogin": "Quay lại Đăng nhập", "forgotPassword": "Quên mật khẩu?", - "defaultPasswordHint": "Default password: CHANGEME (unless INITIAL_PASSWORD was set)", - "Authorization": "Ủy quyền", - "Content-Disposition": "Bố trí nội dung", - "waitingForAuthorization": "Đang chờ cấp phép...", - "waitingForGoogleAuthorization": "Đang chờ Google ủy quyền...", - "waitingForOpenAIAuthorization": "Đang chờ ủy quyền OpenAI...", - "waitingForAntigravityAuthorization": "Đang chờ ủy quyền chống hấp dẫn...", - "waitingForQoderAuthorization": "Đang chờ ủy quyền Qoder...", - "exchangingCodeForTokens": "Đổi mã lấy token...", - "nodeIncompatibleTitle": "Incompatible Node.js Version", - "nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.", - "nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release", - "nodeIncompatibleHint": "OmniRoute requires Node.js 22.22.2+ (22.x LTS) or 24.0.0+ (24.x LTS). Node 24 LTS is recommended." + "defaultPasswordHint": "Mật khẩu mặc định: CHANGEME (trừ khi INITIAL_PASSWORD đã được đặt)", + "Authorization": "Authorization", + "Content-Disposition": "Content-Disposition", + "waitingForAuthorization": "Đang chờ cấp quyền...", + "waitingForGoogleAuthorization": "Đang chờ cấp quyền qua Google...", + "waitingForOpenAIAuthorization": "Đang chờ cấp quyền qua OpenAI...", + "waitingForAntigravityAuthorization": "Đang chờ cấp quyền qua Antigravity...", + "waitingForQoderAuthorization": "Đang chờ cấp quyền qua Qoder...", + "exchangingCodeForTokens": "Đang đổi mã lấy token...", + "nodeIncompatibleTitle": "Phiên bản Node.js không tương thích", + "nodeIncompatibleDesc": "Bạn đang chạy Node.js {version}, phiên bản này nằm ngoài chính sách môi trường chạy an toàn được hỗ trợ của OmniRoute. Vui lòng sử dụng bản phát hành Node.js 20.x hoặc 22.x LTS đã được vá.", + "nodeIncompatibleFixLabel": "Khắc phục: cài đặt bản phát hành Node.js 22 LTS đã được vá", + "nodeIncompatibleHint": "OmniRoute yêu cầu Node.js 22.22.2+ (22.x LTS) hoặc 24.0.0+ (24.x LTS). Khuyến nghị sử dụng Node 24 LTS." }, "landing": { "brandName": "OmniRoute", - "navigateHome": "Điều hướng về nhà", - "toggleMenu": "Chuyển đổi menu", + "navigateHome": "Đi tới trang chủ", + "toggleMenu": "Bật/tắt menu", "featuresLink": "Tính năng", "docsLink": "Tài liệu", "github": "GitHub", - "versionLive": "v1.0 hiện đang hoạt động", - "oneEndpoint": "Một điểm cuối cho", + "versionLive": "v1.0 hiện đã ra mắt", + "oneEndpoint": "Một endpoint duy nhất cho", "allProviders": "Tất cả các nhà cung cấp AI", - "heroDescription": "Proxy điểm cuối AI với bảng điều khiển web - Cổng JavaScript của CLIProxyAPI. Hoạt động liền mạch với Claude Code, OpenAI Codex, Cline, RooCode và các công cụ CLI khác.", + "heroDescription": "Proxy endpoint AI với bảng điều khiển web - Bản chuyển sang JavaScript của CLIProxyAPI. Hoạt động liền mạch với Claude Code, OpenAI Codex, Cline, RooCode và các công cụ CLI khác.", "getStarted": "Bắt đầu", "viewOnGithub": "Xem trên GitHub", "powerfulFeatures": "Tính năng mạnh mẽ", - "featuresSubtitle": "Mọi thứ bạn cần để quản lý cơ sở hạ tầng AI ở một nơi, được xây dựng theo quy mô.", - "featureUnifiedEndpointTitle": "Điểm cuối hợp nhất", + "featuresSubtitle": "Mọi thứ bạn cần để quản lý cơ sở hạ tầng AI tại một nơi, được xây dựng để mở rộng quy mô.", + "featureUnifiedEndpointTitle": "Endpoint hợp nhất", "featureUnifiedEndpointDesc": "Truy cập tất cả các nhà cung cấp thông qua một URL API tiêu chuẩn duy nhất.", "featureEasySetupTitle": "Thiết lập dễ dàng", - "featureEasySetupDesc": "Thiết lập và chạy trong vài phút với lệnh npx.", + "featureEasySetupDesc": "Thiết lập và vận hành chỉ trong vài phút với lệnh npx.", "featureModelFallbackTitle": "Dự phòng mô hình", - "featureModelFallbackDesc": "Tự động chuyển đổi nhà cung cấp khi có lỗi hoặc độ trễ cao.", - "featureUsageTrackingTitle": "Theo dõi sử dụng", + "featureModelFallbackDesc": "Tự động chuyển đổi nhà cung cấp khi xảy ra lỗi hoặc độ trễ cao.", + "featureUsageTrackingTitle": "Theo dõi mức sử dụng", "featureUsageTrackingDesc": "Phân tích chi tiết và giám sát chi phí trên tất cả các mô hình.", - "featureOAuthApiKeysTitle": "Khóa OAuth & API", - "featureOAuthApiKeysDesc": "Quản lý an toàn thông tin xác thực trong một kho tiền.", + "featureOAuthApiKeysTitle": "OAuth & Khóa API", + "featureOAuthApiKeysDesc": "Quản lý an toàn thông tin xác thực trong một kho bảo mật.", "featureCloudSyncTitle": "Đồng bộ đám mây", "featureCloudSyncDesc": "Đồng bộ hóa cấu hình của bạn trên các thiết bị ngay lập tức.", "featureCliSupportTitle": "Hỗ trợ CLI", - "featureCliSupportDesc": "Hoạt động với Claude Code, Codex, Cline, Cursor, v.v.", + "featureCliSupportDesc": "Hoạt động với Claude Code, Codex, Cline, Cursor và các công cụ khác.", "featureDashboardTitle": "Trang tổng quan", - "featureDashboardDesc": "Bảng điều khiển trực quan để phân tích lưu lượng truy cập theo thời gian thực.", + "featureDashboardDesc": "Trang tổng quan trực quan để phân tích lưu lượng truy cập theo thời gian thực.", "howItWorks": "OmniRoute hoạt động như thế nào", - "howItWorksDescription": "Dữ liệu được truyền liền mạch từ ứng dụng của bạn thông qua lớp định tuyến thông minh của chúng tôi đến nhà cung cấp tốt nhất cho công việc.", + "howItWorksDescription": "Dữ liệu được truyền liền mạch từ ứng dụng của bạn thông qua lớp định tuyến thông minh của chúng tôi đến nhà cung cấp phù hợp nhất cho tác vụ.", "howItWorksStep1Title": "1. CLI & SDK", "howItWorksStep1Description": "Yêu cầu của bạn bắt đầu từ các công cụ yêu thích của bạn hoặc SDK hợp nhất của chúng tôi. Chỉ cần thay đổi URL cơ sở.", "howItWorksStep2Title": "2. Trung tâm OmniRoute", - "howItWorksStep2Description": "Công cụ của chúng tôi phân tích lời nhắc, kiểm tra trạng thái của nhà cung cấp và các lộ trình để có độ trễ hoặc chi phí thấp nhất.", + "howItWorksStep2Description": "Công cụ của chúng tôi phân tích prompt, kiểm tra trạng thái hoạt động của nhà cung cấp và định tuyến để có độ trễ hoặc chi phí thấp nhất.", "howItWorksStep3Title": "3. Nhà cung cấp AI", - "howItWorksStep3Description": "Yêu cầu được OpenAI, Anthropic, Gemini hoặc những người khác thực hiện ngay lập tức.", - "getStartedIn30Seconds": "Bắt đầu sau 30 giây", - "getStartedDescription": "Cài đặt OmniRoute, định cấu hình nhà cung cấp của bạn thông qua bảng điều khiển web và bắt đầu định tuyến các yêu cầu AI.", + "howItWorksStep3Description": "Yêu cầu được xử lý ngay lập tức bởi OpenAI, Anthropic, Gemini hoặc các nhà cung cấp khác.", + "getStartedIn30Seconds": "Bắt đầu trong 30 giây", + "getStartedDescription": "Cài đặt OmniRoute, cấu hình các nhà cung cấp của bạn thông qua trang tổng quan web và bắt đầu định tuyến các yêu cầu AI.", "installOmniRoute": "Cài đặt OmniRoute", "installStepDescription": "Chạy lệnh npx để khởi động máy chủ ngay lập tức", "openDashboard": "Mở trang tổng quan", - "openDashboardStepDescription": "Định cấu hình nhà cung cấp và khóa API thông qua giao diện web", - "routeRequests": "Yêu cầu lộ trình", + "openDashboardStepDescription": "Cấu hình các nhà cung cấp và khóa API thông qua giao diện web", + "routeRequests": "Định tuyến yêu cầu", "routeRequestsStepDescription": "Trỏ công cụ CLI của bạn tới {endpoint}", - "terminal": "thiết bị đầu cuối", + "terminal": "terminal", "copy": "Sao chép", - "copied": "✓ Sao chép", + "copied": "✓ Đã sao chép", "startingOmniRoute": "Đang khởi động OmniRoute...", - "serverRunningOnLabel": "Máy chủ đang chạy", + "serverRunningOnLabel": "Máy chủ đang chạy trên", "dashboardLabel": "Trang tổng quan", - "readyToRoute": "Sẵn sàng lên đường! ✓", - "configureProvidersNote": "📝 Định cấu hình nhà cung cấp trong bảng điều khiển hoặc sử dụng biến môi trường", + "readyToRoute": "Sẵn sàng định tuyến! ✓", + "configureProvidersNote": "📝 Cấu hình các nhà cung cấp trong trang tổng quan hoặc sử dụng các biến môi trường", "dataLocation": "Vị trí dữ liệu:", "dataLocationMacLinux": "macOS/Linux:", "dataLocationWindows": "Windows:", - "product": "sản phẩm", + "product": "Sản phẩm", "dashboardLink": "Trang tổng quan", "changelog": "Nhật ký thay đổi", "resources": "Tài nguyên", "documentation": "Tài liệu", "npm": "NPM", - "legal": "pháp lý", + "legal": "Pháp lý", "mitLicense": "Giấy phép MIT", - "footerTagline": "Điểm cuối thống nhất để tạo AI. Kết nối, định tuyến và quản lý các nhà cung cấp AI của bạn một cách dễ dàng.", - "copyright": "© {year} OmniRoute. Mọi quyền được bảo lưu.", - "flowToolClaudeCode": "Mã Claude", - "flowToolOpenAICodex": "Codex OpenAI", + "footerTagline": "Endpoint thống nhất để tạo nội dung bằng AI. Kết nối, định tuyến và quản lý các nhà cung cấp AI của bạn một cách dễ dàng.", + "copyright": "© {year} OmniRoute. Bảo lưu mọi quyền.", + "flowToolClaudeCode": "Claude Code", + "flowToolOpenAICodex": "OpenAI Codex", "flowToolCline": "Cline", - "flowToolCursor": "Con trỏ", + "flowToolCursor": "Cursor", "flowProviderOpenAI": "OpenAI", - "flowProviderAnthropic": "nhân loại", - "flowProviderGemini": "Song Tử", - "flowProviderGithubCopilot": "Phi công phụ GitHub", - "interactiveDiagram": "Sơ đồ tương tác hiển thị trên màn hình", + "flowProviderAnthropic": "Anthropic", + "flowProviderGemini": "Gemini", + "flowProviderGithubCopilot": "GitHub Copilot", + "interactiveDiagram": "Sơ đồ tương tác hiển thị trên máy tính để bàn", "ctaTitle": "Sẵn sàng đơn giản hóa cơ sở hạ tầng AI của bạn?", - "ctaDescription": "Tham gia cùng các nhà phát triển đang hợp lý hóa việc tích hợp AI của họ với OmniRoute. Nguồn mở và miễn phí để bắt đầu.", - "startFree": "Bắt đầu miễn phí", + "ctaDescription": "Tham gia cùng các nhà phát triển đang tối ưu hóa việc tích hợp AI với OmniRoute. Mã nguồn mở và miễn phí để bắt đầu sử dụng.", + "startFree": "Bắt đầu dùng miễn phí", "readDocumentation": "Đọc tài liệu" }, "docs": { @@ -6455,427 +7379,427 @@ "supportedProviders": "Nhà cung cấp được hỗ trợ", "supportedProvidersToc": "Nhà cung cấp", "commonUseCases": "Các trường hợp sử dụng phổ biến", - "clientCompatibility": "Khả năng tương thích của khách hàng", - "protocolsToc": "Protocols", + "clientCompatibility": "Khả năng tương thích của ứng dụng khách", + "protocolsToc": "Giao thức", "apiReference": "Tham chiếu API", - "managementApiReference": "Management API Reference", - "managementApiDescription": "Automation endpoints for proxy registry, scope assignments, and legacy proxy migration.", - "method": "phương pháp", + "managementApiReference": "Tham chiếu API quản lý", + "managementApiDescription": "Các endpoint tự động hóa cho sổ đăng ký proxy, gán phạm vi và di chuyển proxy cũ.", + "method": "Phương thức", "path": "Đường dẫn", "notes": "Ghi chú", - "modelPrefixes": "Tiền tố mẫu", + "modelPrefixes": "Tiền tố mô hình", "prefix": "Tiền tố", "troubleshooting": "Khắc phục sự cố", - "supportsChat": "Hỗ trợ cả điểm cuối trò chuyện và phản hồi.", - "oauthAutoRefresh": "Kết nối OAuth với tính năng làm mới mã thông báo tự động.", - "fullStreaming": "Hỗ trợ phát trực tuyến đầy đủ cho tất cả các kiểu máy.", + "supportsChat": "Hỗ trợ cả endpoint trò chuyện và endpoint phản hồi.", + "oauthAutoRefresh": "Kết nối OAuth với tính năng tự động làm mới token.", + "fullStreaming": "Hỗ trợ truyền phát đầy đủ cho tất cả các mô hình.", "docsLabel": "Tài liệu", - "docsHeroDescription": "Cổng AI cho LLM đa nhà cung cấp. Một điểm cuối cho OpenAI, Anthropic, Gemini, GitHub Copilot, Claude Code, Cursor và hơn 20 nhà cung cấp khác.", + "docsHeroDescription": "Cổng AI cho các LLM đa nhà cung cấp. Một endpoint duy nhất cho OpenAI, Anthropic, Gemini, GitHub Copilot, Claude Code, Cursor và hơn 20 nhà cung cấp khác.", "openDashboard": "Mở trang tổng quan", - "endpointPage": "Trang điểm cuối", + "endpointPage": "Trang endpoint", "github": "GitHub", - "reportIssue": "Báo cáo vấn đề", + "reportIssue": "Báo cáo sự cố", "onThisPage": "Trên trang này", "documentationVersion": "Tài liệu - v{version}", "quickStartStep1Title": "1. Cài đặt và chạy", "quickStartStep1Prefix": "Chạy", "quickStartStep1Middle": "hoặc sao chép từ GitHub và chạy", "quickStartStep2Title": "2. Tạo khóa API", - "quickStartStep2Text": "Đi tới Điểm cuối -> Khóa đã đăng ký. Tạo một khóa cho mỗi môi trường.", + "quickStartStep2Text": "Đi tới Endpoint -> Khóa đã đăng ký. Tạo một khóa cho mỗi môi trường.", "quickStartStep3Title": "3. Kết nối nhà cung cấp", - "quickStartStep3Text": "Thêm tài khoản nhà cung cấp thông qua thông tin đăng nhập OAuth, khóa API hoặc tự động kết nối bậc miễn phí.", - "quickStartStep4Title": "4. Đặt URL cơ sở khách hàng", - "quickStartStep4Prefix": "Trỏ ứng dụng khách IDE hoặc API của bạn tới", + "quickStartStep3Text": "Thêm tài khoản nhà cung cấp thông qua đăng nhập OAuth, khóa API hoặc tự động kết nối với gói miễn phí.", + "quickStartStep4Title": "4. Đặt URL cơ sở cho ứng dụng khách", + "quickStartStep4Prefix": "Trỏ IDE hoặc ứng dụng khách API của bạn đến", "quickStartStep4Suffix": "Sử dụng tiền tố nhà cung cấp, ví dụ", "deploySetupTitle": "Hướng dẫn thiết lập", - "deploySetupText": "Cài đặt từng bước, cấu hình môi trường và hướng dẫn chạy lần đầu cho OmniRoute.", - "deployElectronTitle": "Máy tính để bàn điện tử", + "deploySetupText": "Cài đặt theo từng bước, cấu hình môi trường và hướng dẫn cho lần chạy đầu tiên của OmniRoute.", + "deployElectronTitle": "Electron cho máy tính để bàn", "deployElectronText": "Chạy OmniRoute dưới dạng ứng dụng máy tính để bàn gốc trên Windows, macOS và Linux.", "deployDockerTitle": "Docker", - "deployDockerText": "Triển khai trong vùng chứa với Docker Compose; sẵn sàng cho các ngăn xếp sản xuất và Kubernetes.", + "deployDockerText": "Triển khai dạng container với Docker Compose; sẵn sàng cho các ngăn xếp triển khai trong môi trường sản xuất và Kubernetes.", "deployVmTitle": "Máy ảo", - "deployVmText": "Tự lưu trữ trên mọi máy ảo Linux. Bao gồm đơn vị systemd, xoay vòng nhật ký và công cụ sao lưu.", + "deployVmText": "Tự lưu trữ trên bất kỳ máy ảo Linux nào. Bao gồm đơn vị systemd, xoay vòng nhật ký và công cụ sao lưu.", "deployFlyTitle": "Fly.io", - "deployFlyText": "Triển khai vào thời gian chạy biên Fly.io bằng một fly.toml và một lệnh triển khai duy nhất.", + "deployFlyText": "Triển khai lên môi trường thời gian chạy biên của Fly.io chỉ với một tệp fly.toml và một lệnh triển khai.", "deployPwaTitle": "PWA", - "deployPwaText": "Cài đặt OmniRoute dưới dạng Ứng dụng web lũy tiến trên trình duyệt Android, iOS và máy tính để bàn.", + "deployPwaText": "Cài đặt OmniRoute dưới dạng Progressive Web App trên trình duyệt Android, iOS và máy tính để bàn.", "deployTermuxTitle": "Termux (Android)", - "deployTermuxText": "Run OmniRoute headless on Android via Termux. Access the dashboard from your mobile browser.", + "deployTermuxText": "Chạy OmniRoute không giao diện trên Android qua Termux. Truy cập bảng điều khiển từ trình duyệt di động của bạn.", "featureRoutingTitle": "Định tuyến nhiều nhà cung cấp", - "featureRoutingText": "Định tuyến yêu cầu đến hơn 30 nhà cung cấp AI thông qua một điểm cuối tương thích với OpenAI. Hỗ trợ API trò chuyện, phản hồi, âm thanh và hình ảnh.", - "featureCombosTitle": "Combo và cân bằng", - "featureCombosText": "Tạo các tổ hợp mô hình với chuỗi dự phòng và chiến lược cân bằng: luân phiên, ưu tiên, ngẫu nhiên, ít sử dụng nhất và tối ưu hóa chi phí.", - "featureUsageTitle": "Theo dõi việc sử dụng và chi phí", - "featureUsageText": "Đếm mã thông báo theo thời gian thực, tính toán chi phí cho mỗi nhà cung cấp/mô hình và phân tích mức sử dụng chi tiết theo khóa và tài khoản API.", - "featureAnalyticsTitle": "Trang tổng quan phân tích", - "featureAnalyticsText": "Phân tích trực quan với biểu đồ về yêu cầu, mã thông báo, lỗi, độ trễ, chi phí và mức độ phổ biến của mô hình theo thời gian.", - "featureHealthTitle": "Theo dõi sức khỏe", - "featureHealthText": "Kiểm tra tình trạng trực tiếp, trạng thái nhà cung cấp, trạng thái ngắt mạch và phát hiện giới hạn tốc độ tự động với thời gian chờ theo cấp số nhân.", + "featureRoutingText": "Định tuyến các yêu cầu đến hơn 30 nhà cung cấp AI thông qua một endpoint tương thích với OpenAI. Hỗ trợ các API trò chuyện, phản hồi, âm thanh và hình ảnh.", + "featureCombosTitle": "Tổ hợp và cân bằng", + "featureCombosText": "Tạo các tổ hợp mô hình với chuỗi dự phòng và chiến lược cân bằng: luân phiên, ưu tiên, ngẫu nhiên, ít được sử dụng nhất và tối ưu hóa chi phí.", + "featureUsageTitle": "Theo dõi mức sử dụng và chi phí", + "featureUsageText": "Đếm token theo thời gian thực, tính toán chi phí cho mỗi nhà cung cấp/mô hình và phân tích mức sử dụng chi tiết theo khóa API và tài khoản.", + "featureAnalyticsTitle": "Bảng điều khiển phân tích", + "featureAnalyticsText": "Phân tích trực quan với biểu đồ về các yêu cầu, token, lỗi, độ trễ, chi phí và mức độ phổ biến của mô hình theo thời gian.", + "featureHealthTitle": "Giám sát trạng thái hoạt động", + "featureHealthText": "Kiểm tra tình trạng theo thời gian thực, trạng thái nhà cung cấp, trạng thái bộ ngắt mạch, tự động phát hiện giới hạn tốc độ và chờ lại theo cấp số nhân.", "featureCliTitle": "Công cụ CLI", - "featureCliText": "Quản lý cấu hình IDE, xuất/nhập bản sao lưu, khám phá cấu hình codex và định cấu hình cài đặt từ bảng điều khiển.", + "featureCliText": "Quản lý cấu hình IDE, xuất/nhập bản sao lưu, khám phá các hồ sơ Codex và cấu hình cài đặt từ bảng điều khiển.", "featureSecurityTitle": "Bảo mật và chính sách", - "featureSecurityText": "Xác thực khóa API, lọc IP, bảo vệ tiêm nhắc nhở, chính sách miền, quản lý phiên và ghi nhật ký kiểm tra.", + "featureSecurityText": "Xác thực bằng khóa API, lọc IP, bảo vệ chống chèn prompt, chính sách tên miền, quản lý phiên và ghi nhật ký kiểm toán.", "featureCloudSyncTitle": "Đồng bộ đám mây", - "featureCloudSyncText": "Đồng bộ hóa cấu hình của bạn với Cloudflare Workers để truy cập từ xa bằng thông tin xác thực được mã hóa và chuyển đổi dự phòng tự động.", - "providersAcrossConnectionTypes": "{count} nhà cung cấp trên ba loại kết nối.", + "featureCloudSyncText": "Đồng bộ hóa cấu hình của bạn với Cloudflare Workers để truy cập từ xa bằng thông tin xác thực đã mã hóa và tự động chuyển sang phương án dự phòng.", + "providersAcrossConnectionTypes": "{count} nhà cung cấp thuộc ba loại kết nối.", "manageProviders": "Quản lý nhà cung cấp", "providersCount": "{count} nhà cung cấp", - "providerTypeFree": "Bậc miễn phí", + "providerTypeFree": "Gói miễn phí", "providerTypeOAuth": "OAuth", "providerTypeApiKey": "Khóa API", - "useCaseSingleEndpointTitle": "Điểm cuối duy nhất cho nhiều nhà cung cấp", - "useCaseSingleEndpointText": "Trỏ máy khách đến một URL cơ sở và định tuyến theo tiền tố mô hình (ví dụ: gh/, cc/, kr/, openai/).", - "useCaseFallbackTitle": "Dự phòng và chuyển đổi mô hình bằng combo", - "useCaseFallbackText": "Tạo các mô hình kết hợp trong Bảng điều khiển và giữ cấu hình máy khách ổn định trong khi các nhà cung cấp luân chuyển nội bộ.", - "useCaseUsageVisibilityTitle": "Khả năng hiển thị cách sử dụng, chi phí và gỡ lỗi", - "useCaseUsageVisibilityText": "Theo dõi mã thông báo và chi phí theo nhà cung cấp, tài khoản và khóa API trong tab Sử dụng và Phân tích.", - "clientCherryStudioTitle": "Xưởng Anh Đào", + "useCaseSingleEndpointTitle": "Endpoint duy nhất cho nhiều nhà cung cấp", + "useCaseSingleEndpointText": "Trỏ các ứng dụng khách đến một URL cơ sở và định tuyến theo tiền tố mô hình (ví dụ: gh/, cc/, kr/, openai/).", + "useCaseFallbackTitle": "Dự phòng và chuyển đổi mô hình bằng tổ hợp", + "useCaseFallbackText": "Tạo các mô hình tổ hợp trong Bảng điều khiển và giữ cấu hình ứng dụng khách ổn định trong khi các nhà cung cấp được luân phiên nội bộ.", + "useCaseUsageVisibilityTitle": "Khả năng theo dõi mức sử dụng, chi phí và gỡ lỗi", + "useCaseUsageVisibilityText": "Theo dõi token và chi phí theo nhà cung cấp, tài khoản và khóa API trong các tab Mức sử dụng và Phân tích.", + "clientCherryStudioTitle": "Cherry Studio", "baseUrlLabel": "URL cơ sở", - "chatEndpointLabel": "Điểm cuối trò chuyện", + "chatEndpointLabel": "Endpoint trò chuyện", "modelRecommendationLabel": "Đề xuất mô hình: tiền tố rõ ràng", - "clientCodexTitle": "Mô hình phi công phụ Codex / GitHub", - "clientCodexBullet1": "Sử dụng ID mẫu với", - "clientCodexBullet2": "Các mô hình dòng Codex tự động định tuyến tới", - "clientCodexBullet3": "Các mô hình không phải Codex vẫn tiếp tục", - "clientCursorTitle": "IDE con trỏ", - "clientCursorBullet1": "sử dụng", - "clientCursorBullet1Suffix": "tiền tố cho các mô hình Con trỏ.", + "clientCodexTitle": "Mô hình Codex / GitHub Copilot", + "clientCodexBullet1": "Sử dụng ID mô hình với", + "clientCodexBullet2": "Các mô hình thuộc dòng Codex tự động định tuyến đến", + "clientCodexBullet3": "Các mô hình không thuộc dòng Codex tiếp tục trên", + "clientCursorTitle": "Cursor IDE", + "clientCursorBullet1": "Sử dụng", + "clientCursorBullet1Suffix": "tiền tố cho các mô hình Cursor.", "clientCursorBullet2": "Kết nối OAuth - đăng nhập từ trang Nhà cung cấp.", - "clientClaudeTitle": "Mật mã Claude/Phản trọng lực", - "clientClaudeBullet1Prefix": "sử dụng", + "clientClaudeTitle": "Claude Code / Antigravity", + "clientClaudeBullet1Prefix": "Sử dụng", "clientClaudeBullet1Middle": "(Claude) hoặc", - "clientClaudeBullet1Suffix": "(Phản trọng lực) tiền tố.", - "clientWindsurfTitle": "Lướt ván buồm", - "clientWindsurfBullet1": "Sử dụng OmniRoute làm URL cơ sở tương thích với OpenAI và giữ các tiền tố nhà cung cấp rõ ràng để định tuyến xác định.", + "clientClaudeBullet1Suffix": "tiền tố (Antigravity).", + "clientWindsurfTitle": "Windsurf", + "clientWindsurfBullet1": "Sử dụng OmniRoute làm URL cơ sở tương thích với OpenAI và giữ các tiền tố nhà cung cấp tường minh để định tuyến có tính xác định.", "clientWindsurfBullet2": "Trỏ các mô hình tới `/v1/chat/completions` cho lưu lượng truy cập chung và duy trì `/v1/responses` cho các luồng kiểu Codex.", - "clientWindsurfBullet3": "Sử dụng Bảng điều khiển -> Công cụ CLI để có hướng dẫn cấu hình Windsurf được tạo sẵn.", + "clientWindsurfBullet3": "Sử dụng Bảng điều khiển -> Công cụ CLI để xem hướng dẫn cấu hình Windsurf có sẵn.", "clientClineTitle": "Cline", - "clientClineBullet1": "Cline hoạt động tốt nhất với tiền tố nhà cung cấp/mô hình rõ ràng để bộ định tuyến không bao giờ phải đoán phần phụ trợ.", - "clientClineBullet2": "Sử dụng `/v1/chat/completions` cho các mô hình chung và sử dụng lại cùng một URL cơ sở OmniRoute trên các tài khoản khác nhau.", - "clientClineBullet3": "Sử dụng bảng thông tin Nhà cung cấp để xác thực khóa OAuth/API trước khi gỡ lỗi các vấn đề về thời gian chạy Cline.", - "clientKimiTitle": "Mã hóa Kimi", - "clientKimiBullet1": "Sử dụng OmniRoute làm URL cơ sở ổn định trong khi luân chuyển các tài khoản hoặc tổ hợp nhà cung cấp bên dưới.", - "clientKimiBullet2": "Ưu tiên các mô hình có tiền tố trong luồng mã hóa để quá trình dự phòng và quá trình kiểm tra vẫn rõ ràng.", - "clientKimiBullet3": "Sử dụng `/v1/responses` khi bạn muốn định tuyến kiểu Phản hồi gốc cho các máy khách sử dụng công cụ.", - "protocolsTitle": "Protocols: MCP & A2A", - "protocolsDescription": "OmniRoute exposes two operational protocols in addition to OpenAI-compatible APIs: MCP for tool execution and A2A for agent-to-agent workflows.", + "clientClineBullet1": "Cline hoạt động tốt nhất với các tiền tố nhà cung cấp/mô hình tường minh để bộ định tuyến không bao giờ phải đoán hệ thống phụ trợ.", + "clientClineBullet2": "Sử dụng `/v1/chat/completions` cho các mô hình thông thường và dùng lại cùng một URL cơ sở OmniRoute trên các tài khoản khác nhau.", + "clientClineBullet3": "Sử dụng bảng điều khiển Nhà cung cấp để xác thực OAuth/khóa API trước khi gỡ lỗi các vấn đề khi chạy của Cline.", + "clientKimiTitle": "Kimi Coding", + "clientKimiBullet1": "Sử dụng OmniRoute làm URL cơ sở ổn định trong khi luân phiên các tài khoản hoặc tổ hợp nhà cung cấp ở phía sau.", + "clientKimiBullet2": "Ưu tiên các mô hình có tiền tố trong luồng lập trình để cơ chế dự phòng và nhật ký kiểm tra luôn rõ ràng.", + "clientKimiBullet3": "Sử dụng `/v1/responses` khi bạn muốn định tuyến kiểu Responses gốc cho các ứng dụng khách sử dụng công cụ.", + "protocolsTitle": "Giao thức: MCP & A2A", + "protocolsDescription": "OmniRoute cung cấp hai giao thức vận hành bên cạnh các API tương thích với OpenAI: MCP để thực thi công cụ và A2A cho các quy trình công việc giữa các tác nhân.", "protocolMcpTitle": "MCP (Model Context Protocol)", - "protocolMcpDesc": "Sử dụng MCP qua stdio để cho phép khách hàng khám phá và gọi các công cụ OmniRoute với khả năng hiển thị kiểm tra.", - "protocolMcpStep1": "Bắt đầu vận chuyển MCP với `omniroute --mcp`.", - "protocolMcpStep2": "Trỏ máy khách MCP của bạn tới dịch vụ vận chuyển stdio.", + "protocolMcpDesc": "Sử dụng MCP qua stdio để cho phép ứng dụng khách khám phá và gọi các công cụ OmniRoute, đồng thời có thể theo dõi kiểm toán.", + "protocolMcpStep1": "Khởi động cơ chế truyền tải MCP bằng `omniroute --mcp`.", + "protocolMcpStep2": "Trỏ ứng dụng khách MCP của bạn tới cơ chế truyền tải stdio.", "protocolMcpStep3": "Gọi `omniroute_get_health` và `omniroute_list_combos` để xác thực kết nối.", - "protocolA2aTitle": "A2A (Đại lý2Agent)", - "protocolA2aDesc": "Sử dụng A2A JSON-RPC để gửi tác vụ một cách đồng bộ hoặc thông qua truyền phát SSE.", - "protocolA2aStep1": "Đọc `/.well-known/agent.json` để khám phá tác nhân.", + "protocolA2aTitle": "A2A (Agent2Agent)", + "protocolA2aDesc": "Sử dụng A2A JSON-RPC để gửi tác vụ đồng bộ hoặc qua truyền phát SSE.", + "protocolA2aStep1": "Đọc `/.well-known/agent.json` để phát hiện tác nhân.", "protocolA2aStep2": "Gửi yêu cầu `message/send` hoặc `message/stream` tới `POST /a2a`.", - "protocolA2aStep3": "Quản lý vòng đời tác vụ với `tasks/get` và `tasks/cancel`.", + "protocolA2aStep3": "Quản lý vòng đời tác vụ bằng `tasks/get` và `tasks/cancel`.", "protocolTroubleshootingTitle": "Khắc phục sự cố giao thức", - "protocolTroubleshooting1": "Nếu trạng thái MCP ngoại tuyến, hãy xác minh quy trình stdio đang chạy và tệp nhịp tim đang cập nhật.", - "protocolTroubleshooting2": "If A2A tasks stay in `working`, inspect `/api/a2a/tasks/:id` and stream events for terminal state.", - "protocolTroubleshooting3": "Use `/dashboard/mcp` and `/dashboard/a2a` for operational controls and audit visibility.", + "protocolTroubleshooting1": "Nếu trạng thái MCP là ngoại tuyến, hãy xác minh tiến trình stdio đang chạy và tệp heartbeat đang được cập nhật.", + "protocolTroubleshooting2": "Nếu các tác vụ A2A vẫn ở trạng thái `working`, hãy kiểm tra `/api/a2a/tasks/:id` và các sự kiện luồng để xác định trạng thái kết thúc.", + "protocolTroubleshooting3": "Sử dụng `/dashboard/mcp` và `/dashboard/a2a` để điều khiển vận hành và theo dõi kiểm toán.", "endpointChatNote": "Điểm cuối trò chuyện tương thích với OpenAI (mặc định).", - "endpointResponsesNote": "Điểm cuối API phản hồi (Codex, o-series).", + "endpointResponsesNote": "Điểm cuối API Responses (Codex, o-series).", "endpointModelsNote": "Danh mục mô hình cho tất cả các nhà cung cấp được kết nối.", "endpointAudioNote": "Phiên âm âm thanh (Deepgram, AssemblyAI).", - "endpointSpeechNote": "Tạo văn bản thành giọng nói (ElevenLabs, OpenAI TTS).", - "endpointEmbeddingsNote": "Tạo nhúng văn bản (OpenAI, Cohere, Voyage).", + "endpointSpeechNote": "Tổng hợp giọng nói từ văn bản (ElevenLabs, OpenAI TTS).", + "endpointEmbeddingsNote": "Tạo vector nhúng văn bản (OpenAI, Cohere, Voyage).", "endpointImagesNote": "Tạo hình ảnh (NanoBanana).", - "endpointRewriteChatNote": "Viết lại trình trợ giúp cho khách hàng không có /v1.", - "endpointRewriteResponsesNote": "Viết lại trình trợ giúp cho Phản hồi không có /v1.", - "endpointRewriteModelsNote": "Viết lại trình trợ giúp để khám phá mô hình mà không cần /v1.", - "mgmtProxiesListNote": "List saved proxy registry items (supports pagination).", - "mgmtProxiesCreateNote": "Create a reusable proxy item in the registry.", - "mgmtProxiesHealthNote": "Get 24h/rolling health metrics per saved proxy from proxy logs.", - "mgmtProxiesBulkAssignNote": "Assign or clear one proxy across many scope IDs in one request.", - "mgmtAssignmentsListNote": "List proxy assignments by scope, scope_id, or proxy_id.", - "mgmtAssignmentsUpdateNote": "Assign or clear proxy for global/provider/account/combo scope.", - "mgmtLegacyMigrationNote": "Import legacy proxyConfig maps into registry assignments.", - "modelPrefixesDescriptionStart": "Sử dụng tiền tố nhà cung cấp trước tên mẫu máy để định tuyến đến một nhà cung cấp cụ thể. Ví dụ:", + "endpointRewriteChatNote": "Tiện ích hỗ trợ viết lại cho các ứng dụng khách không có /v1.", + "endpointRewriteResponsesNote": "Tiện ích hỗ trợ viết lại cho Responses không có /v1.", + "endpointRewriteModelsNote": "Tiện ích hỗ trợ viết lại để khám phá mô hình không có /v1.", + "mgmtProxiesListNote": "Liệt kê các mục trong danh mục proxy đã lưu (hỗ trợ phân trang).", + "mgmtProxiesCreateNote": "Tạo một mục proxy có thể tái sử dụng trong danh mục.", + "mgmtProxiesHealthNote": "Lấy các chỉ số sức khỏe 24 giờ/trượt cho từng proxy đã lưu từ nhật ký proxy.", + "mgmtProxiesBulkAssignNote": "Gán hoặc bỏ gán một proxy cho nhiều ID phạm vi trong một yêu cầu.", + "mgmtAssignmentsListNote": "Liệt kê các mục gán proxy theo scope, scope_id hoặc proxy_id.", + "mgmtAssignmentsUpdateNote": "Gán hoặc bỏ gán proxy cho phạm vi global/provider/account/combo.", + "mgmtLegacyMigrationNote": "Nhập các ánh xạ proxyConfig cũ vào các mục gán trong danh mục.", + "modelPrefixesDescriptionStart": "Sử dụng tiền tố nhà cung cấp trước tên mô hình để định tuyến đến một nhà cung cấp cụ thể. Ví dụ:", "modelPrefixesDescriptionEnd": "định tuyến đến GitHub Copilot.", - "provider": "nhà cung cấp", - "type": "loại", - "troubleshootingModelRouting": "Nếu máy khách không định tuyến được mô hình, hãy sử dụng nhà cung cấp/mô hình rõ ràng (ví dụ: gh/gpt-5.1-codex).", - "troubleshootingAmbiguousModels": "Nếu bạn nhận được lỗi mô hình không rõ ràng, hãy chọn tiền tố nhà cung cấp thay vì ID mô hình trần.", - "troubleshootingCodexFamily": "Đối với các mô hình dòng GitHub Codex, hãy giữ mô hình là gh/codex-model; bộ định tuyến chọn/phản hồi tự động.", - "troubleshootingTestConnection": "Sử dụng Trang tổng quan > Nhà cung cấp > Kiểm tra kết nối trước khi thử nghiệm từ IDE hoặc ứng dụng khách bên ngoài.", - "troubleshootingCircuitBreaker": "Nếu nhà cung cấp hiển thị cầu dao đang mở, hãy đợi thời gian hồi chiêu hoặc kiểm tra trang Sức khỏe để biết chi tiết.", - "troubleshootingOAuth": "Đối với nhà cung cấp OAuth, hãy xác thực lại nếu mã thông báo hết hạn. Kiểm tra chỉ báo trạng thái thẻ nhà cung cấp.", - "endpointCompletionsNote": "Điểm cuối hoàn thành kế thừa để tạo văn bản.", + "provider": "Nhà cung cấp", + "type": "Loại", + "troubleshootingModelRouting": "Nếu ứng dụng khách gặp lỗi định tuyến mô hình, hãy sử dụng nhà cung cấp/mô hình rõ ràng (ví dụ: gh/gpt-5.1-codex).", + "troubleshootingAmbiguousModels": "Nếu bạn nhận được lỗi mô hình mơ hồ, hãy chọn tiền tố nhà cung cấp thay vì ID mô hình không kèm tiền tố.", + "troubleshootingCodexFamily": "Đối với các mô hình thuộc dòng GitHub Codex, hãy giữ mô hình là gh/codex-model; bộ định tuyến sẽ tự động chọn /responses.", + "troubleshootingTestConnection": "Sử dụng Trang tổng quan > Nhà cung cấp > Kiểm tra kết nối trước khi kiểm tra từ IDE hoặc các ứng dụng khách bên ngoài.", + "troubleshootingCircuitBreaker": "Nếu một nhà cung cấp hiển thị trạng thái bộ ngắt mạch mở, hãy đợi thời gian hạ nhiệt hoặc kiểm tra trang Sức khỏe để biết chi tiết.", + "troubleshootingOAuth": "Đối với các nhà cung cấp OAuth, hãy xác thực lại nếu token hết hạn. Kiểm tra chỉ báo trạng thái trên thẻ nhà cung cấp.", + "endpointCompletionsNote": "Điểm cuối completions cũ để tạo văn bản.", "endpointModerationsNote": "Kiểm duyệt nội dung và phân loại an toàn.", - "endpointRerankNote": "Sắp xếp lại tài liệu cho thế hệ tăng cường truy xuất (Cohere, Jina).", - "endpointSearchNote": "Tìm kiếm trên web với 5 nhà cung cấp (Serper, Brave, Exa, Tavily, Perplexity).", + "endpointRerankNote": "Sắp xếp lại tài liệu cho tạo sinh tăng cường truy xuất (Cohere, Jina).", + "endpointSearchNote": "Tìm kiếm web với 5 nhà cung cấp (Serper, Brave, Exa, Tavily, Perplexity).", "endpointSearchAnalyticsNote": "Phân tích và số liệu cho các yêu cầu tìm kiếm.", - "endpointVideoNote": "Tạo video (ComfyUI, quy trình làm việc SD WebUI).", - "endpointMusicNote": "Tạo nhạc thông qua quy trình làm việc của ComfyUI.", - "endpointMessagesNote": "Điểm cuối của tin nhắn gốc nhân loại.", - "endpointCountTokensNote": "Đếm mã thông báo cho tải trọng tin nhắn nhất định.", + "endpointVideoNote": "Tạo video (quy trình làm việc ComfyUI, SD WebUI).", + "endpointMusicNote": "Tạo nhạc thông qua quy trình làm việc ComfyUI.", + "endpointMessagesNote": "Điểm cuối messages nguyên bản của Anthropic.", + "endpointCountTokensNote": "Đếm token cho một payload tin nhắn cụ thể.", "endpointFilesNote": "Tải lên tệp cho đầu vào đa phương thức.", - "endpointBatchesNote": "Xử lý hàng loạt các yêu cầu API số lượng lớn.", - "endpointWsNote": "Điểm cuối WebSocket để phát trực tuyến theo thời gian thực.", - "mgmtProvidersListNote": "Liệt kê tất cả các kết nối nhà cung cấp đã đăng ký.", + "endpointBatchesNote": "Xử lý hàng loạt cho các yêu cầu API số lượng lớn.", + "endpointWsNote": "Điểm cuối WebSocket để truyền phát theo thời gian thực.", + "mgmtProvidersListNote": "Liệt kê tất cả kết nối nhà cung cấp đã đăng ký.", "mgmtProvidersCreateNote": "Tạo kết nối nhà cung cấp mới.", "mgmtProvidersUpdateNote": "Cập nhật kết nối nhà cung cấp hiện có.", "mgmtProvidersDeleteNote": "Xóa kết nối nhà cung cấp.", - "mgmtProvidersTestNote": "Kiểm tra kết nối và xác thực cho nhà cung cấp.", - "mgmtProvidersModelsNote": "Liệt kê các mô hình có sẵn cho một nhà cung cấp cụ thể.", - "mgmtSettingsGetNote": "Truy xuất cài đặt ứng dụng hiện tại.", + "mgmtProvidersTestNote": "Kiểm tra kết nối và xác thực cho một nhà cung cấp.", + "mgmtProvidersModelsNote": "Liệt kê các mô hình khả dụng cho một nhà cung cấp cụ thể.", + "mgmtSettingsGetNote": "Lấy cài đặt ứng dụng hiện tại.", "mgmtSettingsUpdateNote": "Cập nhật cài đặt ứng dụng.", - "mgmtPayloadRulesGetNote": "Nhận quy tắc chuyển đổi tải trọng.", - "mgmtPayloadRulesUpdateNote": "Cập nhật quy tắc chuyển đổi tải trọng.", + "mgmtPayloadRulesGetNote": "Lấy các quy tắc biến đổi payload.", + "mgmtPayloadRulesUpdateNote": "Cập nhật các quy tắc biến đổi payload.", "mcpToolsTitle": "Công cụ MCP", - "mcpToolsDescription": "OmniRoute hiển thị các công cụ {count} thông qua Giao thức bối cảnh mô hình để điều phối tác nhân.", + "mcpToolsDescription": "OmniRoute cung cấp {count} công cụ thông qua Model Context Protocol để điều phối tác nhân.", "mcpToolsCount": "{count} công cụ", "mcpToolsToc": "Công cụ MCP", "mcpToolsRoutingTitle": "Định tuyến & Khám phá", - "mcpToolsRoutingDesc": "Kiểm tra tình trạng, quản lý kết hợp, giám sát hạn ngạch, báo cáo chi phí và truy cập danh mục mô hình.", + "mcpToolsRoutingDesc": "Kiểm tra sức khỏe, quản lý combo, giám sát hạn ngạch, báo cáo chi phí và truy cập danh mục mô hình.", "mcpToolsOperationsTitle": "Hoạt động & Chiến lược", - "mcpToolsOperationsDesc": "Mô phỏng tuyến đường, bảo vệ ngân sách, chuyển đổi chiến lược, hồ sơ khả năng phục hồi và số liệu của nhà cung cấp.", - "mcpToolsCacheTitle": "Quản lý bộ đệm", - "mcpToolsCacheDesc": "Xem số liệu thống kê về bộ nhớ đệm và xóa bộ nhớ đệm ngữ nghĩa hoặc chữ ký.", - "mcpToolsCompressionTitle": "Động cơ nén", - "mcpToolsCompressionDesc": "Định cấu hình nén RTK/Brotli, công cụ trao đổi và kiểm tra phân tích nén bằng cách kết hợp.", + "mcpToolsOperationsDesc": "Mô phỏng định tuyến, bảo vệ ngân sách, chuyển đổi chiến lược, hồ sơ khả năng phục hồi và số liệu của nhà cung cấp.", + "mcpToolsCacheTitle": "Quản lý cache", + "mcpToolsCacheDesc": "Xem số liệu thống kê cache và xóa sạch cache ngữ nghĩa hoặc cache chữ ký.", + "mcpToolsCompressionTitle": "Công cụ nén", + "mcpToolsCompressionDesc": "Cấu hình nén RTK/Brotli, hoán đổi công cụ và kiểm tra số liệu phân tích nén theo từng tổ hợp.", "mcpToolsOneProxyTitle": "1Proxy / Đường hầm", - "mcpToolsOneProxyDesc": "Quản lý proxy gửi đi, xoay vòng IP dân cư và kiểm tra tình trạng proxy.", + "mcpToolsOneProxyDesc": "Quản lý proxy đầu ra, xoay vòng IP dân dụng và kiểm tra tình trạng proxy.", "mcpToolsMemoryTitle": "Bộ nhớ", - "mcpToolsMemoryDesc": "Tìm kiếm, thêm và xóa các mục bộ nhớ đàm thoại liên tục.", + "mcpToolsMemoryDesc": "Tìm kiếm, thêm và xóa các mục trong bộ nhớ hội thoại lâu dài.", "mcpToolsSkillsTitle": "Kỹ năng", - "mcpToolsSkillsDesc": "Liệt kê, kích hoạt, thực thi và giám sát việc thực hiện kỹ năng tùy chỉnh.", - "featureAutoComboTitle": "Tự động kết hợp", - "featureAutoComboText": "Tự động tạo các combo được tối ưu hóa dựa trên nhà cung cấp được kết nối, kiểu sử dụng và khả năng của mô hình.", - "featureSearchTitle": "Tìm kiếm trên web", - "featureSearchText": "Tìm kiếm trên web tích hợp với 5 nhà cung cấp (Serper, Brave, Exa, Tavily, Perplexity) bao gồm phân tích và theo dõi chi phí.", + "mcpToolsSkillsDesc": "Liệt kê, kích hoạt, thực thi và giám sát việc thực thi kỹ năng tùy chỉnh.", + "featureAutoComboTitle": "Tổ hợp tự động", + "featureAutoComboText": "Tự động tạo các tổ hợp tối ưu dựa trên các nhà cung cấp đã kết nối, mẫu sử dụng và khả năng của mô hình.", + "featureSearchTitle": "Tìm kiếm web", + "featureSearchText": "Tích hợp tìm kiếm web với 5 nhà cung cấp (Serper, Brave, Exa, Tavily, Perplexity) bao gồm phân tích và theo dõi chi phí.", "featureMemoryTitle": "Hệ thống bộ nhớ", - "featureMemoryText": "Bộ nhớ đàm thoại liên tục với khả năng trích xuất, chèn, truy xuất và tóm tắt qua các phiên.", + "featureMemoryText": "Bộ nhớ hội thoại lâu dài với các tính năng trích xuất, chèn, truy xuất và tóm tắt giữa các phiên.", "featureSkillsTitle": "Khung kỹ năng", - "featureSkillsText": "Hệ thống kỹ năng mở rộng với các kỹ năng tích hợp và tùy chỉnh, thực thi hộp cát, chặn yêu cầu và chèn ngữ cảnh.", - "featureAcpTitle": "Truyền thông đại lý", - "featureAcpText": "Sổ đăng ký Giao thức Truyền thông Tác nhân (ACP) để quản lý quy trình công việc giữa các tác nhân và điều phối công cụ.", - "protocolAcpTitle": "ACP (Truyền thông đại lý)", - "protocolAcpDesc": "Đăng ký và quản lý các tác nhân thông qua sổ đăng ký ACP để liên lạc giữa các tác nhân và chia sẻ công cụ.", - "protocolAcpStep1": "Điều hướng đến Bảng điều khiển → Đại lý để xem các đại lý ACP đã đăng ký.", - "protocolAcpStep2": "Đăng ký các đại lý mới với khả năng và cấu hình điểm cuối.", - "protocolAcpStep3": "Sử dụng Công cụ CLI để định cấu hình các kênh liên lạc của tổng đài viên." + "featureSkillsText": "Hệ thống kỹ năng có thể mở rộng với các kỹ năng tích hợp và tùy chỉnh, thực thi trong sandbox, chặn yêu cầu và chèn ngữ cảnh.", + "featureAcpTitle": "Giao tiếp giữa các tác nhân", + "featureAcpText": "Sổ đăng ký Giao thức giao tiếp tác nhân (ACP) để quản lý quy trình làm việc giữa các tác nhân và điều phối công cụ.", + "protocolAcpTitle": "ACP (Giao tiếp giữa các tác nhân)", + "protocolAcpDesc": "Đăng ký và quản lý các tác nhân thông qua sổ đăng ký ACP để giao tiếp giữa các tác nhân và chia sẻ công cụ.", + "protocolAcpStep1": "Điều hướng đến Dashboard → Agents để xem các tác nhân ACP đã đăng ký.", + "protocolAcpStep2": "Đăng ký các tác nhân mới với các khả năng và cấu hình endpoint.", + "protocolAcpStep3": "Sử dụng các công cụ CLI để cấu hình các kênh giao tiếp của tác nhân." }, "legal": { - "privacyPolicy": "Chính sách bảo mật", + "privacyPolicy": "Chính sách quyền riêng tư", "termsOfService": "Điều khoản dịch vụ", "providerConfigurations": "Cấu hình nhà cung cấp", "apiKeys": "Khóa API", "usageLogs": "Nhật ký sử dụng", "applicationSettings": "Cài đặt ứng dụng", - "viewExportAnalytics": "Xem và xuất phân tích sử dụng", - "clearHistory": "Xóa lịch sử sử dụng bất cứ lúc nào", - "configureRetention": "Định cấu hình chính sách lưu giữ nhật ký", + "viewExportAnalytics": "Xem và xuất phân tích mức sử dụng", + "clearHistory": "Xóa lịch sử mức sử dụng bất kỳ lúc nào", + "configureRetention": "Cấu hình các chính sách lưu giữ nhật ký", "backupRestore": "Sao lưu và khôi phục cơ sở dữ liệu của bạn", - "privacyMetadataTitle": "Chính sách bảo mật | OmniRoute", - "privacyMetadataDescription": "Chính sách quyền riêng tư dành cho bộ định tuyến proxy OmniRoute AI API.", + "privacyMetadataTitle": "Chính sách quyền riêng tư | OmniRoute", + "privacyMetadataDescription": "Chính sách quyền riêng tư dành cho bộ định tuyến proxy API AI của OmniRoute.", "termsMetadataTitle": "Điều khoản dịch vụ | OmniRoute", "termsMetadataDescription": "Điều khoản dịch vụ dành cho bộ định tuyến proxy OmniRoute AI API.", - "backToHome": "Trở về nhà", + "backToHome": "Quay lại trang chủ", "lastUpdated": "Cập nhật lần cuối: {date}", "policyLastUpdatedDate": "Ngày 13 tháng 2 năm 2026", "listSeparator": "-", - "questionsVisit": "Câu hỏi? Ghé thăm của chúng tôi", - "githubRepository": "Kho lưu trữ GitHub", - "privacySection1Title": "1. Kiến trúc địa phương đầu tiên", - "privacySection1Text": "OmniRoute được thiết kế như một ứng dụng cục bộ đầu tiên. Tất cả quá trình xử lý và lưu trữ dữ liệu diễn ra hoàn toàn trên máy của bạn. Không có máy chủ tập trung thu thập thông tin của bạn.", + "questionsVisit": "Có câu hỏi? Hãy truy cập", + "githubRepository": "kho lưu trữ GitHub của chúng tôi", + "privacySection1Title": "1. Kiến trúc ưu tiên cục bộ", + "privacySection1Text": "OmniRoute được thiết kế như một ứng dụng ưu tiên cục bộ. Mọi quá trình xử lý và lưu trữ dữ liệu đều diễn ra hoàn toàn trên máy của bạn. Không có máy chủ trung tâm nào thu thập thông tin của bạn.", "privacySection2Title": "2. Dữ liệu chúng tôi lưu trữ", - "privacyDataStoredIn": "Dữ liệu sau được lưu trữ cục bộ trong", - "privacyDataProviderConfigurationsDesc": "URL kết nối, loại nhà cung cấp và cài đặt ưu tiên", + "privacyDataStoredIn": "Các dữ liệu sau được lưu trữ cục bộ trong", + "privacyDataProviderConfigurationsDesc": "URL kết nối, loại nhà cung cấp và các cài đặt ưu tiên", "privacyDataApiKeysDesc": "được mã hóa và lưu trữ cục bộ để xác thực với các nhà cung cấp AI", - "privacyDataUsageLogsDesc": "số lượng yêu cầu, mức sử dụng mã thông báo, tên mô hình, dấu thời gian và thời gian phản hồi", - "privacyDataApplicationSettingsDesc": "tùy chọn chủ đề, chiến lược định tuyến và cấu hình kết hợp", - "privacySection3Title": "3. Không đo từ xa", - "privacySection3Text": "OmniRoute không thu thập báo cáo đo từ xa, phân tích hoặc sự cố. Không có dữ liệu nào được gửi cho chúng tôi hoặc bất kỳ bên thứ ba nào. Kiểu sử dụng, lệnh gọi API và cấu hình của bạn vẫn hoàn toàn ở chế độ riêng tư.", - "privacySection4Title": "4. Nhà cung cấp AI bên thứ ba", - "privacySection4Text": "Khi bạn thực hiện lệnh gọi API thông qua OmniRoute, yêu cầu của bạn sẽ được chuyển tiếp đến nhà cung cấp AI mà bạn đã định cấu hình (ví dụ: OpenAI, Anthropic, Google). Các nhà cung cấp này có chính sách bảo mật riêng chi phối cách họ xử lý dữ liệu của bạn. Vui lòng xem lại:", - "privacyOpenAiPolicy": "Chính sách quyền riêng tư của OpenAI", - "privacyAnthropicPolicy": "Chính sách về quyền riêng tư của Anthropic", + "privacyDataUsageLogsDesc": "số lượng yêu cầu, mức sử dụng token, tên mô hình, dấu thời gian và thời gian phản hồi", + "privacyDataApplicationSettingsDesc": "tùy chọn giao diện, chiến lược định tuyến và cấu hình kết hợp", + "privacySection3Title": "3. Không thu thập dữ liệu đo từ xa", + "privacySection3Text": "OmniRoute không thu thập dữ liệu đo từ xa, dữ liệu phân tích hoặc báo cáo sự cố. Không có dữ liệu nào được gửi cho chúng tôi hoặc bất kỳ bên thứ ba nào. Thói quen sử dụng, các lệnh gọi API và cài đặt cấu hình của bạn hoàn toàn được giữ riêng tư.", + "privacySection4Title": "4. Các nhà cung cấp AI bên thứ ba", + "privacySection4Text": "Khi bạn thực hiện các lệnh gọi API thông qua OmniRoute, các yêu cầu của bạn sẽ được chuyển tiếp đến các nhà cung cấp AI mà bạn đã cấu hình (ví dụ: OpenAI, Anthropic, Google). Các nhà cung cấp này có chính sách bảo mật riêng chi phối cách họ xử lý dữ liệu của bạn. Vui lòng xem lại:", + "privacyOpenAiPolicy": "Chính sách bảo mật của OpenAI", + "privacyAnthropicPolicy": "Chính sách bảo mật của Anthropic", "privacyGooglePolicy": "Chính sách bảo mật của Google", "privacySection5Title": "5. Đồng bộ hóa đám mây (Tùy chọn)", - "privacySection5Text": "Nếu bạn bật tính năng đồng bộ hóa đám mây tùy chọn, cấu hình nhà cung cấp và khóa API có thể được truyền đến điểm cuối đám mây đã định cấu hình. Tính năng này bị tắt theo mặc định và yêu cầu chọn tham gia rõ ràng.", + "privacySection5Text": "Nếu bạn bật tính năng đồng bộ hóa đám mây tùy chọn, cấu hình nhà cung cấp và khóa API có thể được truyền tới một endpoint đám mây đã cấu hình. Tính năng này bị tắt theo mặc định và yêu cầu bạn chủ động đồng ý tham gia.", "privacySection6Title": "6. Ghi nhật ký", - "privacyLoggingIntro": "Nhật ký yêu cầu có thể được cấu hình thông qua cài đặt bảng điều khiển. Bạn có thể:", + "privacyLoggingIntro": "Nhật ký yêu cầu có thể được cấu hình trong cài đặt của bảng điều khiển. Bạn có thể:", "privacySection7Title": "7. Quyền của bạn", "privacySection7TextStart": "Vì tất cả dữ liệu được lưu trữ cục bộ nên bạn có toàn quyền kiểm soát. Bạn có thể xóa dữ liệu của mình bất kỳ lúc nào bằng cách xóa", "privacySection7TextEnd": "thư mục hoặc sử dụng tính năng sao lưu và khôi phục cơ sở dữ liệu trong bảng điều khiển.", "termsSection1Title": "1. Tổng quan", - "termsSection1Text": "OmniRoute là bộ định tuyến proxy AI API cục bộ đầu tiên hoạt động hoàn toàn trên máy của bạn. Nó định tuyến các yêu cầu đến nhiều nhà cung cấp AI với tính năng cân bằng tải, chuyển đổi dự phòng và theo dõi việc sử dụng.", - "termsSection2Title": "2. Trách nhiệm của Người dùng", - "termsResponsibilityApiKeys": "Bạn hoàn toàn chịu trách nhiệm quản lý khóa API và thông tin đăng nhập của riêng mình cho các nhà cung cấp AI bên thứ ba (OpenAI, Anthropic, Google, v.v.).", - "termsResponsibilityCompliance": "Bạn phải tuân thủ các điều khoản dịch vụ của từng nhà cung cấp AI có API mà bạn truy cập thông qua OmniRoute.", - "termsResponsibilitySecurity": "Bạn chịu trách nhiệm về tính bảo mật của cài đặt OmniRoute cục bộ của mình, bao gồm đặt mật khẩu và hạn chế quyền truy cập mạng.", - "termsSection3Title": "3. Nó hoạt động như thế nào", - "termsSection3Text": "OmniRoute hoạt động như một proxy trung gian. Các lệnh gọi API gửi tới OmniRoute sẽ được dịch và chuyển tiếp đến các nhà cung cấp AI đã định cấu hình của bạn. OmniRoute không sửa đổi nội dung yêu cầu hoặc phản hồi của bạn ngoài bản dịch giao thức cần thiết.", + "termsSection1Text": "OmniRoute là bộ định tuyến proxy API AI ưu tiên cục bộ hoạt động hoàn toàn trên máy của bạn. Nó định tuyến các yêu cầu đến nhiều nhà cung cấp AI với tính năng cân bằng tải, chuyển đổi dự phòng và theo dõi mức sử dụng.", + "termsSection2Title": "2. Trách nhiệm của người dùng", + "termsResponsibilityApiKeys": "Bạn hoàn toàn chịu trách nhiệm quản lý khóa API và thông tin xác thực của riêng mình cho các nhà cung cấp AI bên thứ ba (OpenAI, Anthropic, Google, v.v.).", + "termsResponsibilityCompliance": "Bạn phải tuân thủ các điều khoản dịch vụ của từng nhà cung cấp AI mà bạn truy cập API của họ thông qua OmniRoute.", + "termsResponsibilitySecurity": "Bạn chịu trách nhiệm về tính bảo mật của bản cài đặt OmniRoute cục bộ của mình, bao gồm việc đặt mật khẩu và hạn chế quyền truy cập mạng.", + "termsSection3Title": "3. Cách thức hoạt động", + "termsSection3Text": "OmniRoute hoạt động như một proxy trung gian. Các lệnh gọi API gửi đến OmniRoute sẽ được chuyển đổi và chuyển tiếp đến các nhà cung cấp AI đã được cấu hình của bạn. OmniRoute không sửa đổi nội dung của các yêu cầu hoặc phản hồi ngoài việc chuyển đổi giao thức cần thiết.", "termsSection4Title": "4. Xử lý dữ liệu", "termsDataStoredLocally": "Tất cả dữ liệu được lưu trữ cục bộ trên máy của bạn trong cơ sở dữ liệu SQLite.", - "termsNoTransmission": "OmniRoute không truyền bất kỳ dữ liệu nào đến các máy chủ bên ngoài trừ khi bạn bật rõ ràng các tính năng đồng bộ hóa trên đám mây.", - "termsDataLocationText": "Nhật ký sử dụng, khóa API và cấu hình được lưu trữ trong", + "termsNoTransmission": "OmniRoute không truyền bất kỳ dữ liệu nào đến các máy chủ bên ngoài trừ khi bạn bật rõ ràng các tính năng đồng bộ hóa đám mây.", + "termsDataLocationText": "Nhật ký mức sử dụng, khóa API và cấu hình được lưu trữ trong", "termsSection5Title": "5. Tuyên bố từ chối trách nhiệm", - "termsSection5Text": "OmniRoute được cung cấp \"nguyên trạng\" mà không có bất kỳ hình thức bảo hành nào. Chúng tôi không chịu trách nhiệm về bất kỳ chi phí nào phát sinh do sử dụng API, gián đoạn dịch vụ hoặc mất dữ liệu. Luôn duy trì bản sao lưu cấu hình của bạn.", - "termsSection6Title": "6. Nguồn mở", - "termsSection6Text": "OmniRoute là phần mềm mã nguồn mở. Bạn có thể tự do kiểm tra, sửa đổi và phân phối nó theo các điều khoản trong giấy phép." + "termsSection5Text": "OmniRoute được cung cấp \"nguyên trạng\" mà không có bất kỳ hình thức bảo hành nào. Chúng tôi không chịu trách nhiệm về bất kỳ chi phí nào phát sinh do sử dụng API, gián đoạn dịch vụ hoặc mất dữ liệu. Luôn duy trì bản sao lưu cho cấu hình của bạn.", + "termsSection6Title": "6. Mã nguồn mở", + "termsSection6Text": "OmniRoute là phần mềm mã nguồn mở. Bạn có thể tự do kiểm tra, sửa đổi và phân phối phần mềm theo các điều khoản trong giấy phép của nó." }, "agents": { - "title": "CLI Agents", - "description": "Discover installed CLI agents on your system. Add custom agents for auto-detection.", - "refresh": "Refresh", - "installed": "Installed", - "notFound": "Not Found", - "builtIn": "Built-in", - "custom": "Custom", - "remove": "Remove", - "addCustomAgent": "Add Custom Agent", - "addCustomAgentDesc": "Register any CLI tool for detection. It will be scanned automatically on refresh.", - "agentName": "Agent Name", - "binaryName": "Binary Name", - "versionCommand": "Version Command", - "spawnArgs": "Spawn Args", - "addAgent": "Add Agent", - "scanning": "Scanning system for CLI agents...", - "opencodeIntegration": "OpenCode Integration", - "opencodeDetected": "opencode {version} detected", - "opencodeDesc": "Generate a ready-to-use {configFile} with your OmniRoute base URL and all available models — drop it in your project root and run {command}.", - "downloadConfig": "Download {file}", - "downloaded": "Downloaded!", - "setupGuideTitle": "Setup guide", - "openCliTools": "Open CLI Tools", - "setupGuideDetectCliTitle": "Detect installed CLIs", - "setupGuideDetectCliDesc": "Click Refresh after installing or updating a CLI so OmniRoute can rescan binaries and versions.", - "setupGuideCustomAgentTitle": "Register custom binary", - "setupGuideCustomAgentDesc": "Use Add Custom Agent when your CLI is not in the built-in list. Provide binary name and version command.", - "setupGuideCommandMissingTitle": "Fix 'command not found'", - "setupGuideCommandMissingDesc": "Ensure the CLI command exists in PATH, open a new terminal session, and rerun Refresh.", - "cliToolsRedirectTitle": "Cli Tools Redirect Title", - "cliToolsRedirectDesc": "Cli Tools Redirect Desc", - "spawnArgsPlaceholder": "Spawn Args Placeholder", - "binaryNamePlaceholder": "Binary Name Placeholder", - "versionCommandPlaceholder": "Version Command Placeholder", - "architectureTitle": "Architecture Title", - "flowLocalBinary": "Flow Local Binary", - "flowOmniRoute": "Flow Omni Route", - "agentNamePlaceholder": "Agent Name Placeholder", - "architectureDescription": "Architecture Description", - "flowExecute": "Flow Execute", - "flowSpawn": "Flow Spawn", - "cliToolsRedirectCta": "Cli Tools Redirect Cta", - "comparisonTitle": "Công cụ CLI so với mục tiêu đại lý - Sự khác biệt là gì?", - "comparisonCliToolsLabel": "Trang công cụ CLI", - "comparisonCliToolsTitle": "IDE của bạn gửi yêu cầu thông qua OmniRoute", - "comparisonCliToolsDesc": "Định cấu hình Claude Code, Codex, Cursor và các IDE khác để sử dụng OmniRoute làm URL cơ sở API của chúng. OmniRoute hoạt động như một proxy, định tuyến các yêu cầu đến các nhà cung cấp đã định cấu hình của bạn.", - "comparisonAgentsLabel": "Trang này (Mục tiêu của đại lý)", + "title": "Tác nhân CLI", + "description": "Khám phá các tác nhân CLI đã cài đặt trên hệ thống của bạn. Thêm các tác nhân tùy chỉnh để tự động phát hiện.", + "refresh": "Làm mới", + "installed": "Đã cài đặt", + "notFound": "Không tìm thấy", + "builtIn": "Tích hợp sẵn", + "custom": "Tùy chỉnh", + "remove": "Gỡ bỏ", + "addCustomAgent": "Thêm tác nhân tùy chỉnh", + "addCustomAgentDesc": "Đăng ký bất kỳ công cụ CLI nào để hệ thống phát hiện. Công cụ sẽ được quét tự động khi làm mới.", + "agentName": "Tên tác nhân", + "binaryName": "Tên tệp nhị phân", + "versionCommand": "Lệnh kiểm tra phiên bản", + "spawnArgs": "Đối số khởi chạy", + "addAgent": "Thêm tác nhân", + "scanning": "Đang quét hệ thống để tìm các tác nhân CLI...", + "opencodeIntegration": "Tích hợp OpenCode", + "opencodeDetected": "Đã phát hiện opencode {version}", + "opencodeDesc": "Tạo tệp {configFile} sẵn sàng sử dụng với URL cơ sở OmniRoute của bạn và tất cả mô hình có sẵn — đặt tệp này vào thư mục gốc của dự án rồi chạy lệnh {command}.", + "downloadConfig": "Tải xuống {file}", + "downloaded": "Đã tải xuống!", + "setupGuideTitle": "Hướng dẫn thiết lập", + "openCliTools": "Mở công cụ CLI", + "setupGuideDetectCliTitle": "Phát hiện các CLI đã cài đặt", + "setupGuideDetectCliDesc": "Nhấp vào Làm mới sau khi cài đặt hoặc cập nhật một CLI để OmniRoute có thể quét lại các tệp nhị phân và phiên bản.", + "setupGuideCustomAgentTitle": "Đăng ký tệp nhị phân tùy chỉnh", + "setupGuideCustomAgentDesc": "Sử dụng Thêm tác nhân tùy chỉnh khi CLI của bạn không có trong danh sách tích hợp sẵn. Cung cấp tên tệp nhị phân và lệnh kiểm tra phiên bản.", + "setupGuideCommandMissingTitle": "Khắc phục lỗi 'command not found'", + "setupGuideCommandMissingDesc": "Đảm bảo lệnh CLI tồn tại trong PATH, mở một phiên terminal mới và chạy lại Làm mới.", + "cliToolsRedirectTitle": "Bạn muốn cấu hình IDE của mình?", + "cliToolsRedirectDesc": "Nếu bạn muốn trỏ Claude Code, Cursor, Codex hoặc bất kỳ IDE nào đến OmniRoute dưới dạng proxy, hãy chuyển sang trang Công cụ CLI. Trang này dành cho chiều ngược lại — sử dụng các tệp nhị phân CLI cục bộ làm mục tiêu thực thi mà OmniRoute có thể khởi chạy và định tuyến yêu cầu qua đó.", + "spawnArgsPlaceholder": "Ví dụ: --quiet, --json, --no-auto-commits", + "binaryNamePlaceholder": "Ví dụ: my-agent hoặc /usr/local/bin/llm-cli", + "versionCommandPlaceholder": "Ví dụ: my-agent --version", + "architectureTitle": "Cách hoạt động của mục tiêu tác nhân", + "flowLocalBinary": "3 · Tiến trình CLI với thông tin xác thực riêng", + "flowOmniRoute": "1 · Yêu cầu gửi đến OmniRoute", + "agentNamePlaceholder": "Ví dụ: Tác nhân tùy chỉnh của tôi", + "architectureDescription": "Khi một yêu cầu đến, OmniRoute có thể khởi chạy một tệp nhị phân CLI cục bộ (ví dụ: claude, codex, goose) và chuyển yêu cầu qua đó. CLI sẽ xử lý yêu cầu bằng thông tin xác thực riêng và trả kết quả về qua OmniRoute.", + "flowExecute": "4 · Phản hồi được trả về cho ứng dụng khách", + "flowSpawn": "2 · OmniRoute khởi chạy tệp nhị phân cục bộ", + "cliToolsRedirectCta": "Đi đến Công cụ CLI →", + "comparisonTitle": "Công cụ CLI so với Mục tiêu tác nhân — Sự khác biệt là gì?", + "comparisonCliToolsLabel": "Trang Công cụ CLI", + "comparisonCliToolsTitle": "IDE của bạn gửi các yêu cầu thông qua OmniRoute", + "comparisonCliToolsDesc": "Cấu hình Claude Code, Codex, Cursor và các IDE khác sử dụng OmniRoute làm URL cơ sở API của chúng. OmniRoute hoạt động như một proxy, định tuyến các yêu cầu đến các nhà cung cấp đã cấu hình của bạn.", + "comparisonAgentsLabel": "Trang này (Mục tiêu tác nhân)", "comparisonAgentsTitle": "OmniRoute gửi yêu cầu đến các công cụ CLI cục bộ", - "comparisonAgentsDesc": "OmniRoute có thể sinh ra các tệp nhị phân CLI cục bộ (claude, codex, ngỗng) làm phần phụ trợ thực thi. Công cụ CLI xử lý yêu cầu bằng xác thực của chính nó và trả về kết quả.", - "comparisonSummary": "Tóm lại: Công cụ CLI = bạn định cấu hình các công cụ để trỏ tới OmniRoute. Mục tiêu tác nhân = OmniRoute sử dụng các công cụ làm điểm cuối.", + "comparisonAgentsDesc": "OmniRoute có thể khởi chạy các tệp nhị phân CLI cục bộ (claude, codex, goose) làm phần phụ trợ thực thi. Công cụ CLI xử lý yêu cầu bằng thông tin xác thực riêng và trả về kết quả.", + "comparisonSummary": "Nói ngắn gọn: Công cụ CLI = bạn cấu hình các công cụ để trỏ đến OmniRoute. Mục tiêu tác nhân = OmniRoute sử dụng các công cụ làm endpoint của mình.", "agentUseCaseHint": "Có thể được sử dụng làm mục tiêu thực thi thông qua giao thức ACP", "flowDiagramClient": "Ứng dụng khách", - "flowDiagramClientDesc": "SDK, API hoặc dịch vụ ngược dòng", + "flowDiagramClientDesc": "SDK, API hoặc dịch vụ thượng nguồn", "flowDiagramOmniRoute": "OmniRoute", "flowDiagramOmniRouteDesc": "Nhận yêu cầu và chọn mục tiêu", - "flowDiagramSpawn": "Quá trình sinh sản", - "flowDiagramSpawnDesc": "Khởi chạy nhị phân CLI qua stdio", - "flowDiagramCli": "Đại lý CLI", + "flowDiagramSpawn": "Tạo tiến trình", + "flowDiagramSpawnDesc": "Khởi chạy tệp nhị phân CLI qua stdio", + "flowDiagramCli": "Tác nhân CLI", "flowDiagramCliDesc": "Các quy trình có xác thực/mô hình riêng", - "fingerprintSettingsHint": "Kết hợp dấu vân tay CLI (ngụy trang các yêu cầu dưới dạng công cụ CLI cụ thể) có thể được định cấu hình trong", + "fingerprintSettingsHint": "Có thể cấu hình tính năng đối sánh dấu vân tay CLI (ngụy trang các yêu cầu thành các công cụ CLI cụ thể) trong", "settingsRoutingLink": "Cài đặt/Định tuyến", "openSettings": "Cài đặt", - "copyRawUrlTitle": "Sao chép URL thô vào clipboard", + "copyRawUrlTitle": "Sao chép URL thô vào bộ nhớ tạm", "copied": "Đã sao chép!", "copyUrl": "Sao chép URL", - "startHere": "Bắt đầu ở đây", + "startHere": "Bắt đầu tại đây", "badgeNew": "Mới", "viewOnGithub": "Xem trên GitHub", - "howToUse": "Cách sử dụng", - "browseAllSkillsOnGithub": "Duyệt tất cả các kỹ năng trên GitHub", + "howToUse": "Hướng dẫn sử dụng", + "browseAllSkillsOnGithub": "Xem tất cả kỹ năng trên GitHub", "apiSkills": "Kỹ năng API", "cliSkills": "Kỹ năng CLI", - "apiSkillsSubtitle": "__MISSING__:{count} skills — control OmniRoute via REST / HTTP", - "cliSkillsSubtitle": "__MISSING__:{count} skills — control OmniRoute via the omniroute terminal binary", - "howToUseStep1": "__MISSING__:Click {copyUrl} on the skill you want your agent to know about.", - "howToUseStep2": "__MISSING__:In your AI agent (Claude, Cursor, Cline…), say:", - "howToUseStep2Code": "__MISSING__:Use the skill at [pasted-url]", - "howToUseStep3": "__MISSING__:The agent fetches the SKILL.md and learns OmniRoute's API or CLI — no manual docs needed." + "apiSkillsSubtitle": "{count} kỹ năng — điều khiển OmniRoute qua REST / HTTP", + "cliSkillsSubtitle": "{count} kỹ năng — điều khiển OmniRoute qua tệp thực thi omniroute trong terminal", + "howToUseStep1": "Nhấp vào {copyUrl} trên kỹ năng bạn muốn tác nhân của mình tìm hiểu.", + "howToUseStep2": "Trong tác nhân AI của bạn (Claude, Cursor, Cline…), hãy nói:", + "howToUseStep2Code": "Sử dụng kỹ năng tại [pasted-url]", + "howToUseStep3": "Tác nhân sẽ tải SKILL.md và tự học API hoặc CLI của OmniRoute — không cần đọc tài liệu thủ công." }, "cloudAgents": { - "title": "Đại lý đám mây", - "description": "Quản lý các tác nhân mã hóa tự trị (Jules, Devin, Codex Cloud)", - "loading": "Đang tải nhiệm vụ...", - "aboutTitle": "Giới thiệu về Đại lý đám mây", - "aboutDescription": "Tác nhân đám mây là trợ lý mã hóa AI từ xa có thể thực hiện các tác vụ một cách tự động. Chúng hoạt động khác với các tác nhân CLI địa phương - bạn tương tác với chúng thông qua API của OmniRoute.", - "howItWorksTitle": "Nó hoạt động như thế nào:", - "howItWorksDesc": "Tạo nhiệm vụ → Đại lý phân tích và đề xuất phương án → Bạn phê duyệt → Đại lý thực thi → Kết quả trả về", - "newTaskTitle": "Tạo nhiệm vụ mới", - "newTaskDescription": "Bắt đầu nhiệm vụ mới với tác nhân đám mây", - "selectAgent": "Chọn đại lý", - "taskDescription": "Mô tả nhiệm vụ", - "taskDescriptionPlaceholder": "Mô tả những gì bạn muốn người đại diện làm...", - "startTask": "Bắt đầu nhiệm vụ", - "tasks": "Nhiệm vụ", - "taskDetail": "Chi tiết nhiệm vụ", - "noTasks": "Chưa có nhiệm vụ nào. Tạo một cái để bắt đầu.", - "noTasksTitle": "__MISSING__:No tasks yet", - "noTasksDesc": "__MISSING__:Create your first task to get started.", - "tasksTab": "__MISSING__:Tasks", - "agentsTab": "__MISSING__:Agents", - "settingsTab": "__MISSING__:Settings", - "agentsEnabled": "__MISSING__:Enabled", - "agentsDisabled": "__MISSING__:Disabled", - "filterAllProviders": "__MISSING__:All Providers", - "filterAll": "__MISSING__:All", - "autoRefreshing": "__MISSING__:Auto-refreshing", - "viewPR": "__MISSING__:View Pull Request", - "connected": "__MISSING__:Connected", - "notConnected": "__MISSING__:Not connected", - "configure": "__MISSING__:Configure", - "settingsTitle": "__MISSING__:Cloud Agent Settings", - "settingsDesc": "__MISSING__:Configure local preferences for cloud agents.", - "settingEnableAgents": "__MISSING__:Enable cloud agents", - "settingEnableAgentsDesc": "__MISSING__:Allow OmniRoute to orchestrate autonomous coding agents.", - "settingAutoPR": "__MISSING__:Auto-create PR", - "settingAutoPRDesc": "__MISSING__:When a task is completed, automatically create a Pull Request with the changes.", - "settingRequireApproval": "__MISSING__:Require plan approval", - "settingRequireApprovalDesc": "__MISSING__:Always wait for manual approval before an agent executes a proposed plan.", - "untitledTask": "Nhiệm vụ không có tiêu đề", + "title": "Cloud Agents", + "description": "Quản lý các tác nhân lập trình tự chủ (Jules, Devin, Codex Cloud)", + "loading": "Đang tải các tác vụ...", + "aboutTitle": "Giới thiệu về Tác nhân đám mây", + "aboutDescription": "Tác nhân đám mây là trợ lý lập trình AI từ xa có thể thực hiện các tác vụ một cách tự chủ. Chúng hoạt động khác với các tác nhân CLI cục bộ - bạn tương tác với chúng thông qua API của OmniRoute.", + "howItWorksTitle": "Cách thức hoạt động:", + "howItWorksDesc": "Tạo tác vụ → Tác nhân phân tích và đề xuất kế hoạch → Bạn phê duyệt → Tác nhân thực thi → Trả về kết quả", + "newTaskTitle": "Tạo tác vụ mới", + "newTaskDescription": "Bắt đầu một tác vụ mới với tác nhân đám mây", + "selectAgent": "Chọn tác nhân", + "taskDescription": "Mô tả tác vụ", + "taskDescriptionPlaceholder": "Mô tả những gì bạn muốn tác nhân thực hiện...", + "startTask": "Bắt đầu tác vụ", + "tasks": "Tác vụ", + "taskDetail": "Chi tiết tác vụ", + "noTasks": "Chưa có tác vụ nào. Hãy tạo một tác vụ để bắt đầu.", + "noTasksTitle": "Chưa có tác vụ nào", + "noTasksDesc": "Tạo tác vụ đầu tiên của bạn để bắt đầu.", + "tasksTab": "Tác vụ", + "agentsTab": "Tác nhân", + "settingsTab": "Cài đặt", + "agentsEnabled": "Đã bật", + "agentsDisabled": "Đã tắt", + "filterAllProviders": "Tất cả nhà cung cấp", + "filterAll": "Tất cả", + "autoRefreshing": "Tự động làm mới", + "viewPR": "Xem Pull Request", + "connected": "Đã kết nối", + "notConnected": "Chưa kết nối", + "configure": "Cấu hình", + "settingsTitle": "Cài đặt tác nhân đám mây", + "settingsDesc": "Cấu hình các tùy chọn cục bộ cho tác nhân đám mây.", + "settingEnableAgents": "Bật tác nhân đám mây", + "settingEnableAgentsDesc": "Cho phép OmniRoute điều phối các tác nhân lập trình tự chủ.", + "settingAutoPR": "Tự động tạo PR", + "settingAutoPRDesc": "Tự động tạo một Pull Request với các thay đổi khi một nhiệm vụ hoàn thành.", + "settingRequireApproval": "Yêu cầu phê duyệt kế hoạch", + "settingRequireApprovalDesc": "Luôn chờ phê duyệt thủ công trước khi tác nhân thực thi kế hoạch được đề xuất.", + "untitledTask": "Tác vụ không có tiêu đề", "created": "Đã tạo", "conversation": "Cuộc trò chuyện", - "result": "kết quả", + "result": "Kết quả", "error": "Lỗi", "planReady": "Kế hoạch đã sẵn sàng để phê duyệt", "approvePlan": "Phê duyệt kế hoạch", - "rejectPlan": "Từ chối & Hủy bỏ", - "sendMessagePlaceholder": "Gửi tin nhắn cho đại lý...", - "cancel": "Hủy bỏ", + "rejectPlan": "Từ chối & Hủy", + "sendMessagePlaceholder": "Gửi tin nhắn cho tác nhân...", + "cancel": "Hủy", "delete": "Xóa", - "selectTaskPrompt": "Chọn nhiệm vụ để xem chi tiết", + "selectTaskPrompt": "Chọn một nhiệm vụ để xem chi tiết", "statusPending": "Đang chờ xử lý", "statusRunning": "Đang chạy", - "statusWaitingApproval": "Đang chờ phê duyệt", + "statusWaitingApproval": "Chờ phê duyệt", "statusCompleted": "Đã hoàn thành", - "statusFailed": "thất bại", + "statusFailed": "Thất bại", "statusCancelled": "Đã hủy", "repositoryName": "Tên kho lưu trữ", "repositoryUrl": "URL kho lưu trữ", - "branch": "chi nhánh" + "branch": "Nhánh" }, "templateNames": { "simple-chat": "Trò chuyện đơn giản", - "streaming": "Truyền phát", + "streaming": "Truyền trực tuyến", "system-prompt": "Lời nhắc hệ thống", - "thinking": "suy nghĩ", + "thinking": "Suy nghĩ", "tool-calling": "Gọi công cụ", "multi-turn": "Nhiều lượt", - "vision": "Tầm nhìn", - "schema-coercion": "Lược đồ cưỡng bức" + "vision": "Thị giác", + "schema-coercion": "Ép kiểu lược đồ" }, "templateDescriptions": { - "simple-chat": "Mẫu chat cơ bản kèm tin nhắn hệ thống", - "streaming": "Mẫu để truyền phát phản hồi", + "simple-chat": "Mẫu trò chuyện cơ bản kèm thông điệp hệ thống", + "streaming": "Mẫu cho phản hồi truyền trực tuyến", "system-prompt": "Mẫu có lời nhắc hệ thống tùy chỉnh", - "thinking": "Mẫu có ngân sách lý luận/suy nghĩ", - "tool-calling": "Mẫu để gọi công cụ/chức năng", - "multi-turn": "Mẫu hội thoại nhiều lượt", - "vision": "Mẫu đa phương thức có đầu vào hình ảnh", - "schema-coercion": "Thực thi lược đồ JSON/đầu ra có cấu trúc" + "thinking": "Mẫu có ngân sách suy nghĩ/lý luận", + "tool-calling": "Mẫu để gọi công cụ/hàm", + "multi-turn": "Mẫu cho hội thoại nhiều lượt", + "vision": "Mẫu đa phương thức với đầu vào hình ảnh", + "schema-coercion": "Ép buộc đầu ra có cấu trúc / lược đồ JSON" }, "templatePayloads": { "simpleChat": { @@ -6890,172 +7814,172 @@ "systemInstruction": "Đưa ra một câu trả lời sâu sắc và mang tính triết lý." }, "thinking": { - "question": "Giải thích tính toán lượng tử" + "question": "Giải thích về tính toán lượng tử" }, "toolCalling": { - "cityNameDescription": "Tên của thành phố để biết thời tiết", - "toolDescription": "Nhận thời tiết hiện tại cho một địa điểm", + "cityNameDescription": "Tên của thành phố để lấy thông tin thời tiết", + "toolDescription": "Lấy thông tin thời tiết hiện tại cho một địa điểm", "userWeather": "Thời tiết ở Tokyo thế nào?" }, "multiTurn": { "system": "Bạn là một trợ lý hữu ích.", - "assistantExample": "Tôi rất vui được giúp bạn việc đó.", - "userInitial": "Tôi cần giúp đỡ với", - "userFollowUp": "Bạn có thể giải thích về điều đó?" + "assistantExample": "Tôi rất sẵn lòng giúp bạn việc đó.", + "userInitial": "Tôi cần trợ giúp về", + "userFollowUp": "Bạn có thể giải thích chi tiết hơn về điều đó không?" } }, "cache": { - "title": "Cache Management", - "description": "Monitor and manage semantic response cache, hit rates, and token savings.", - "refresh": "Refresh", - "clearAll": "Clear All", - "memoryEntries": "Memory Entries", - "memoryEntriesSub": "In-memory LRU", - "dbEntries": "DB Entries", - "dbEntriesSub": "Persisted (SQLite)", - "cacheHits": "Cache Hits", - "cacheHitsSub": "of {total} total", - "tokensSaved": "Tokens Saved", - "tokensSavedSub": "Estimated from hits", - "hitRate": "Hit Rate", - "performance": "Cache Performance", - "autoRefresh": "Auto-refreshes every {seconds}s", - "hits": "Hits", - "misses": "Misses", - "total": "Total", - "behavior": "Cache Behavior", - "behaviorDeterministic": "Only non-streaming requests with temperature=0 are cached.", - "behaviorBypass": "Bypass with header {header}.", - "behaviorTwoTier": "Two-tier storage: in-memory LRU (fast) + SQLite (persistent across restarts).", - "behaviorTtl": "Default TTL: 30 minutes. Configure via {envVar}.", - "idempotency": "Idempotency Layer", - "activeDedupKeys": "Active Dedup Keys", - "dedupWindow": "Dedup Window", - "clearSuccess": "Cache cleared. {count} expired entries removed.", - "clearError": "Failed to clear cache.", - "unavailable": "Cache unavailable", - "unavailableDesc": "Could not fetch cache statistics. Make sure the server is running.", - "loadingCacheAria": "__MISSING__:Loading cache", - "promptCache": "Prompt Cache (Provider-Side)", - "semanticCache": "Semantic Cache", - "promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.", - "promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.", - "cachedRequests": "Cached Requests", - "cachedRequests24h": "Cached Requests (24h)", - "cacheHitRate": "Cache Hit Rate", - "cacheRate": "Cache Rate", - "cacheRateDesc": "of total requests", - "cachedTokens": "Cached Tokens", - "cacheCreationTokens": "Cache Creation Tokens", - "cacheMetrics": "Prompt Cache Metrics", - "withCacheControl": "With Cache Control", - "cachedTokensRead": "Cached Tokens (Read)", - "cacheCreationWrite": "Cache Creation (Write)", - "cacheReuseRatio": "Cache Reuse Ratio", - "cacheReuseRatioDesc": "Cached tokens / Total input tokens", - "estCostSaved": "Est. Cost Saved", - "lastUpdated": "Last updated", - "hoursTracked": "hours tracked", - "busiestHour": "Busiest Hour", - "peakCacheRate": "Peak Cache Rate", - "trendHour": "Hour", - "activityVolume": "Activity", - "requestsShort": "reqs", - "inputShort": "In", - "cachedShort": "Cached", - "writeShort": "Write", - "resetting": "Resetting...", - "resetMetrics": "Reset Metrics", - "byProvider": "Breakdown by Provider", - "providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.", - "provider": "Provider", - "requests": "Requests", - "inputTokens": "Input Tokens", - "cachedTokensCol": "Cached", - "cacheCreation": "Creation", - "trend24h": "Cache Trend (24h)", - "peakCached": "Peak cached", - "cached": "Cached", - "overview": "Overview", - "tableProvider": "__MISSING__:Provider", - "tableModel": "__MISSING__:Model", - "performanceTitle": "__MISSING__:Performance", - "semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.", - "semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.", - "semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.", - "searchEntries": "Search entries...", - "search": "Search", - "loading": "Loading...", - "entriesLoadError": "Failed to load semantic cache entries.", - "noEntries": "No cache entries found", - "noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.", - "noTrendData": "No prompt cache activity has been recorded over the last 24 hours.", - "signature": "Signature", - "model": "Model", - "created": "Created", - "expires": "Expires", - "actions": "Actions", - "deduplicatedRequests": "Deduplicated Requests", - "savedCalls": "Saved API Calls", - "totalProcessed": "Total Requests Processed", - "disabled": "Disabled", - "totalRequests": "Total Requests", - "reasoningCache": "Phát lại lý luận", - "reasoningCacheDesc": "Duy trì tư duy mô hình cho các luồng gọi công cụ nhiều lượt", - "reasoningEntries": "Mục hoạt động", + "title": "Quản lý cache", + "description": "Giám sát hiệu quả cache prompt của nhà cung cấp và việc tái sử dụng phản hồi ngữ nghĩa cục bộ.", + "refresh": "Làm mới", + "clearAll": "Xóa Cache ngữ nghĩa", + "memoryEntries": "Bản ghi bộ nhớ", + "memoryEntriesSub": "LRU trong bộ nhớ", + "dbEntries": "Bản ghi cơ sở dữ liệu", + "dbEntriesSub": "Lưu trữ lâu dài (SQLite)", + "cacheHits": "Lượt truy cập cache thành công", + "cacheHitsSub": "trong tổng số {total}", + "tokensSaved": "Token đã tiết kiệm", + "tokensSavedSub": "Ước tính từ các lượt truy cập cache thành công", + "hitRate": "Tỷ lệ truy cập cache thành công", + "performance": "Hiệu suất Cache", + "autoRefresh": "Tự động làm mới mỗi {seconds} giây", + "hits": "Lượt truy cập cache thành công", + "misses": "Lượt truy cập cache không thành công", + "total": "Tổng số", + "behavior": "Hành vi Cache", + "behaviorDeterministic": "Chỉ các yêu cầu không truyền trực tuyến có temperature=0 mới được lưu vào cache.", + "behaviorBypass": "Bỏ qua bằng header {header}.", + "behaviorTwoTier": "Lưu trữ hai lớp: LRU trong bộ nhớ (nhanh) + SQLite (lưu trữ lâu dài giữa các lần khởi động lại).", + "behaviorTtl": "TTL mặc định: 30 phút. Cấu hình qua {envVar}.", + "idempotency": "Lớp đảm bảo tính lũy đẳng", + "activeDedupKeys": "Các khóa khử trùng lặp đang hoạt động", + "dedupWindow": "Khoảng thời gian khử trùng lặp", + "clearSuccess": "Đã xóa cache ngữ nghĩa. Đã xóa {count} bản ghi.", + "clearError": "Không thể xóa cache.", + "unavailable": "Cache không khả dụng", + "unavailableDesc": "Không thể lấy số liệu thống kê cache. Hãy đảm bảo máy chủ đang hoạt động.", + "loadingCacheAria": "Đang tải cache", + "promptCache": "Prompt Cache (Phía nhà cung cấp)", + "semanticCache": "Cache ngữ nghĩa", + "promptCacheSectionDesc": "Hiển thị hoạt động lưu vào prompt cache phía nhà cung cấp từ lịch sử mức sử dụng để bạn biết tính năng kiểm soát cache đang hoạt động ở đâu và lượng đầu vào được tái sử dụng.", + "promptTrendDesc": "Lượng yêu cầu theo giờ, mức độ bao phủ của cache và lượng dữ liệu đọc từ cache trong 24 giờ qua.", + "cachedRequests": "Yêu cầu đã được lưu vào cache", + "cachedRequests24h": "Yêu cầu đã được lưu vào cache (24 giờ)", + "cacheHitRate": "Tỷ lệ trúng cache", + "cacheRate": "Tỷ lệ cache", + "cacheRateDesc": "trên tổng số yêu cầu", + "cachedTokens": "Token đọc từ cache", + "cacheCreationTokens": "Token ghi vào cache", + "cacheMetrics": "Chỉ số prompt cache", + "withCacheControl": "Có kiểm soát cache", + "cachedTokensRead": "Đọc từ cache", + "cacheCreationWrite": "Ghi vào cache", + "cacheReuseRatio": "Tỷ lệ tái sử dụng cache", + "cacheReuseRatioDesc": "Token đọc từ cache / Tổng số token đầu vào", + "estCostSaved": "Chi phí tiết kiệm ước tính", + "lastUpdated": "Cập nhật lần cuối", + "hoursTracked": "giờ được theo dõi", + "busiestHour": "Giờ bận rộn nhất", + "peakCacheRate": "Tỷ lệ cache cao nhất", + "trendHour": "Giờ", + "activityVolume": "Hoạt động", + "requestsShort": "yêu cầu", + "inputShort": "Đầu vào", + "cachedShort": "Đã lưu cache", + "writeShort": "Ghi", + "resetting": "Đang đặt lại...", + "resetMetrics": "Đặt lại chỉ số", + "byProvider": "Chi tiết theo nhà cung cấp", + "providerCacheRateDesc": "Mỗi nhà cung cấp hiển thị tổng số token đầu vào, token đọc từ cache và token ghi vào cache để bạn có thể xác minh tỷ lệ tái sử dụng dựa trên tổng số liệu gốc.", + "provider": "Nhà cung cấp", + "requests": "Yêu cầu", + "inputTokens": "Tổng số token đầu vào", + "cachedTokensCol": "Đọc từ cache", + "cacheCreation": "Ghi vào cache", + "trend24h": "Xu hướng cache (24 giờ)", + "peakCached": "Đỉnh điểm cache", + "cached": "Đã lưu cache", + "overview": "Tổng quan", + "tableProvider": "Nhà cung cấp", + "tableModel": "Mô hình", + "performanceTitle": "Hiệu suất", + "semanticCacheSectionDesc": "Bộ nhớ đệm phản hồi tất định của riêng OmniRoute. Khi được bật, các yêu cầu lặp lại không phát trực tuyến với `temperature=0` có thể được xử lý cục bộ mà không cần gửi đến nhà cung cấp thượng nguồn.", + "semanticCacheDisabledDesc": "Bộ nhớ đệm ngữ nghĩa đã bị tắt. OmniRoute sẽ bỏ qua việc tái sử dụng phản hồi cục bộ cho đến khi bạn bật lại trong cài đặt.", + "semanticEntriesDesc": "Các bản ghi bộ nhớ đệm ngữ nghĩa được lưu trữ lâu dài trong SQLite. Hoạt động prompt cache phía nhà cung cấp không được liệt kê ở đây.", + "searchEntries": "Tìm kiếm mục...", + "search": "Tìm kiếm", + "loading": "Đang tải...", + "entriesLoadError": "Không thể tải các mục bộ nhớ đệm ngữ nghĩa.", + "noEntries": "Không tìm thấy mục bộ nhớ đệm nào", + "noPromptCacheData": "Chưa có hoạt động prompt cache phía nhà cung cấp nào được ghi lại.", + "noTrendData": "Không có hoạt động prompt cache nào được ghi lại trong 24 giờ qua.", + "signature": "Chữ ký", + "model": "Mô hình", + "created": "Đã tạo", + "expires": "Hết hạn", + "actions": "Hành động", + "deduplicatedRequests": "Yêu cầu đã được khử trùng lặp", + "savedCalls": "Số cuộc gọi API tiết kiệm được", + "totalProcessed": "Tổng số yêu cầu đã xử lý", + "disabled": "Đã tắt", + "totalRequests": "Tổng số yêu cầu", + "reasoningCache": "Phát lại suy luận", + "reasoningCacheDesc": "Lưu giữ quá trình suy luận của mô hình cho các luồng gọi công cụ nhiều lượt", + "reasoningEntries": "Các mục đang hoạt động", "reasoningReplayRate": "Tỷ lệ phát lại", "reasoningReplays": "Tổng số lượt phát lại", - "reasoningCharsCached": "Ký tự được lưu vào bộ nhớ đệm", - "reasoningMisses": "Thiếu bộ nhớ đệm", + "reasoningCharsCached": "Ký tự đã lưu cache", + "reasoningMisses": "Số lần bỏ lỡ bộ nhớ đệm", "reasoningByProvider": "Theo nhà cung cấp", - "reasoningByModel": "Theo mẫu", - "reasoningRecentEntries": "Bài viết gần đây", + "reasoningByModel": "Theo mô hình", + "reasoningRecentEntries": "Các mục gần đây", "reasoningToolCallId": "ID cuộc gọi công cụ", - "reasoningChars": "nhân vật", - "reasoningAge": "Tuổi", + "reasoningChars": "Ký tự", + "reasoningAge": "Thời gian tồn tại", "reasoningView": "Xem", - "reasoningDetail": "Nội dung lý luận", + "reasoningDetail": "Nội dung suy luận", "reasoningBehavior": "Hành vi", - "reasoningBehaviorCapture": "Ghi lại Reason_content từ các phản hồi trực tuyến", - "reasoningBehaviorReplay": "Tiêm lại ở lượt tiếp theo khi khách hàng bỏ qua", - "reasoningBehaviorFallback": "Ưu tiên bộ nhớ với dự phòng SQLite để khắc phục sự cố", - "reasoningBehaviorTtl": "TTL: 2 giờ | Mục nhập tối đa: 2.000 (bộ nhớ)", + "reasoningBehaviorCapture": "Ghi lại `reasoning_content` từ các phản hồi truyền phát", + "reasoningBehaviorReplay": "Chèn lại vào lượt tiếp theo khi ứng dụng khách bỏ qua nội dung này", + "reasoningBehaviorFallback": "Ưu tiên bộ nhớ với dự phòng SQLite để phục hồi khi gặp sự cố", + "reasoningBehaviorTtl": "TTL: 2 giờ | Số mục tối đa: 2.000 (bộ nhớ)", "reasoningBehaviorModels": "Được hỗ trợ: DeepSeek, Kimi, Qwen-Thinking, GLM", - "reasoningClearAll": "Xóa bộ nhớ đệm lý luận", - "reasoningClearSuccess": "Đã xóa {count} mục nhập bộ đệm lý luận", - "reasoningClearError": "Không xóa được bộ nhớ đệm lý do", - "reasoningNoData": "Chưa có mục lý luận nào được lưu vào bộ nhớ đệm. Các mục xuất hiện khi các mô hình tư duy sử dụng cách gọi công cụ.", + "reasoningClearAll": "Xóa bộ nhớ đệm suy luận", + "reasoningClearSuccess": "Đã xóa {count} mục trong bộ nhớ đệm suy luận", + "reasoningClearError": "Không thể xóa bộ nhớ đệm suy luận", + "reasoningNoData": "Chưa có mục suy luận nào được lưu vào bộ nhớ đệm. Các mục sẽ xuất hiện khi mô hình suy luận gọi công cụ.", "cachePerformanceRetry": "Thử lại", - "cachePerformanceHitRate": "Tỷ lệ trúng", + "cachePerformanceHitRate": "Tỷ lệ truy cập bộ nhớ đệm thành công", "cachePerformanceAvgLatency": "Độ trễ trung bình (ms)", - "cachePerformanceP95Latency": "p95 Độ trễ (ms)", + "cachePerformanceP95Latency": "Độ trễ p95 (ms)", "retry": "Thử lại", - "reasoningAvgChars": "Ký tự trung bình", - "tableShare": "__MISSING__:Share", - "justNow": "__MISSING__:just now", - "minutesAgo": "__MISSING__:{minutes}m ago", - "hoursAgo": "__MISSING__:{hours}h ago", - "daysAgo": "__MISSING__:{days}d ago", - "entries": "Entries" + "reasoningAvgChars": "Số ký tự trung bình", + "tableShare": "Chia sẻ", + "justNow": "vừa mới", + "minutesAgo": "{minutes} phút trước", + "hoursAgo": "{hours} giờ trước", + "daysAgo": "{days} ngày trước", + "entries": "Mục" }, "proxyConfigModal": { "levelGlobal": "Toàn cầu", - "levelProvider": "nhà cung cấp", - "levelCombo": "kết hợp", - "levelKey": "Chìa khóa", - "levelDirect": "Trực tiếp (không có proxy)", + "levelProvider": "Nhà cung cấp", + "levelCombo": "Combo", + "levelKey": "Khóa", + "levelDirect": "Trực tiếp (không dùng proxy)", "titleGlobal": "Cấu hình proxy toàn cầu", - "titleLevel": "{level} Ủy quyền — {label}", + "titleLevel": "{level} Proxy — {label}", "loading": "Đang tải cấu hình proxy...", "inheritingFrom": "Kế thừa từ", "source": "Nguồn", "savedProxy": "Proxy đã lưu", - "custom": "tùy chỉnh", + "custom": "Tùy chỉnh", "selectSavedProxyPlaceholder": "Chọn proxy đã lưu...", "proxyType": "Loại proxy", "host": "Máy chủ", "hostPlaceholder": "1.2.3.4 hoặc proxy.example.com", - "port": "Cảng", + "port": "Cổng", "authOptional": "Xác thực (tùy chọn)", "username": "Tên người dùng", "usernamePlaceholder": "Tên người dùng", @@ -7063,37 +7987,37 @@ "passwordPlaceholder": "Mật khẩu", "connected": "Đã kết nối", "ip": "IP:", - "connectionFailed": "Kết nối không thành công", + "connectionFailed": "Kết nối thất bại", "testConnection": "Kiểm tra kết nối", "clear": "Xóa", - "cancel": "Hủy bỏ", + "cancel": "Hủy", "save": "Lưu", - "errorSelectSavedProxy": "Vui lòng chọn proxy đã lưu trước.", - "errorSelectProxyFirst": "Vui lòng chọn proxy trước.", + "errorSelectSavedProxy": "Vui lòng chọn một proxy đã lưu trước.", + "errorSelectProxyFirst": "Vui lòng chọn một proxy trước.", "errorProxyNotFound": "Không tìm thấy proxy đã chọn.", - "errorClearSavedProxy": "Không xóa được proxy đã lưu", - "errorSaveProxy": "Không lưu được cấu hình proxy", - "errorClearProxy": "Không xóa được cấu hình proxy", - "errorSocks5Hidden": "SOCKS5 được định cấu hình nhưng bị ẩn vì NEXT_PUBLIC_ENABLE_SOCKS5_PROXY=false." + "errorClearSavedProxy": "Không thể xóa proxy đã lưu", + "errorSaveProxy": "Không thể lưu cấu hình proxy", + "errorClearProxy": "Không thể xóa cấu hình proxy", + "errorSocks5Hidden": "SOCKS5 đã được cấu hình nhưng bị ẩn vì NEXT_PUBLIC_ENABLE_SOCKS5_PROXY=false." }, "oauthModal": { "title": "Kết nối {providerName}", - "waiting": "Đang chờ cấp phép", - "completeAuthInPopup": "Hoàn thành ủy quyền trong cửa sổ bật lên.", - "popupClosedHint": "Nếu cửa sổ bật lên đóng mà không chuyển hướng trở lại (ví dụ: Qoder), hộp thoại này sẽ tự động chuyển sang chế độ nhập URL thủ công.", - "popupBlocked": "Cửa sổ bật lên bị chặn? Nhập URL theo cách thủ công", + "waiting": "Đang chờ ủy quyền", + "completeAuthInPopup": "Hoàn tất ủy quyền trong cửa sổ bật lên.", + "popupClosedHint": "Nếu cửa sổ bật lên đóng hoặc không thể chuyển tiếp lệnh gọi lại, hộp thoại này sẽ tự động chuyển sang chế độ nhập URL thủ công.", + "popupBlocked": "Cửa sổ bật lên bị chặn? Nhập URL thủ công", "deviceCodeVisitUrl": "Truy cập URL bên dưới và nhập mã:", "deviceCodeVerificationUrl": "URL xác minh", "deviceCodeYourCode": "Mã của bạn", - "deviceCodeWaiting": "Đang chờ cấp phép...", - "googleOAuthWarning": "Truy cập từ xa + Google OAuth: Thông tin xác thực mặc định chỉ chấp nhận chuyển hướng đến localhost. Sau khi ủy quyền, trình duyệt của bạn sẽ cố mở localhost — sao chép URL đầy đủ đó và dán vào bên dưới. Để sử dụng hoàn toàn từ xa mà không cần bước thủ công này, hãy định cấu hình thông tin xác thực OAuth của riêng bạn.", + "deviceCodeWaiting": "Đang chờ ủy quyền...", + "googleOAuthWarning": "Truy cập từ xa + Google OAuth: thông tin xác thực đi kèm chỉ chấp nhận các chuyển hướng loopback như 127.0.0.1. Trình duyệt phê duyệt Google phải có thể kết nối với OmniRoute trên cổng cục bộ đó, thường bằng cách mở OmniRoute cục bộ hoặc sử dụng đường hầm SSH/chuyển tiếp cục bộ. Khuyến nghị cho các cài đặt từ xa: trên máy tính của chính bạn, hãy chạy npx omniroute login antigravity và dán khối thông tin xác thực mà lệnh in ra vào trường bên dưới. Để sử dụng hoàn toàn từ xa mà không có chuyển hướng cục bộ này, hãy định cấu hình thông tin xác thực OAuth của riêng bạn.", "remoteAccessInfo": "Truy cập từ xa: Vì bạn đang truy cập OmniRoute từ xa nên sau khi ủy quyền, bạn sẽ thấy một trang lỗi (không tìm thấy localhost). Điều này là bình thường — chỉ cần sao chép toàn bộ URL từ thanh địa chỉ trình duyệt của bạn và dán vào bên dưới.", "step1OpenUrl": "Bước 1: Mở URL này trong trình duyệt của bạn", "copy": "Sao chép", - "step2PasteCallback": "Bước 2: Dán URL gọi lại hoặc mã ủy quyền tại đây", - "step2Hint": "Sau khi ủy quyền, dán URL gọi lại đầy đủ. Đối với Mã Claude và Cline, bạn cũng có thể dán trực tiếp mã xác thực, ví dụ: code#state.", + "step2PasteCallback": "Bước 2: Dán URL chuyển hướng hoặc mã ủy quyền vào đây", + "step2Hint": "Sau khi ủy quyền, hãy dán URL chuyển hướng đầy đủ. Đối với Claude Code và Cline, bạn cũng có thể dán trực tiếp mã xác thực, ví dụ: code#state.", "connect": "Kết nối", - "cancel": "Hủy bỏ", + "cancel": "Hủy", "success": "Kết nối thành công!", "successMessage": "Tài khoản {providerName} của bạn đã được kết nối.", "done": "Xong", @@ -7101,387 +8025,466 @@ "tryAgain": "Thử lại" }, "cursorAuthModal": { - "title": "Kết nối con trỏ IDE", - "autoDetecting": "Tự động phát hiện mã thông báo...", - "readingFromCursor": "Đọc từ IDE con trỏ hoặc tác nhân con trỏ", - "tokensAutoDetected": "Mã thông báo được tự động phát hiện thành công từ Cursor IDE!", - "cursorNotDetected": "IDE con trỏ không được phát hiện. Vui lòng dán mã thông báo của bạn theo cách thủ công.", - "accessToken": "Mã thông báo truy cập", + "title": "Kết nối Cursor IDE", + "autoDetecting": "Tự động phát hiện token...", + "readingFromCursor": "Đang đọc token từ Cursor IDE hoặc cursor-agent", + "tokensAutoDetected": "Đã tự động phát hiện token từ Cursor IDE thành công!", + "cursorNotDetected": "Không phát hiện thấy Cursor IDE. Vui lòng dán token của bạn thủ công.", + "accessToken": "Token truy cập", "required": "*", - "accessTokenPlaceholder": "Mã thông báo truy cập sẽ tự động điền...", - "machineId": "ID máy", + "accessTokenPlaceholder": "Token truy cập sẽ được tự động điền...", + "machineId": "Mã máy", "optional": "(tùy chọn)", - "machineIdPlaceholder": "ID máy sẽ tự động điền...", - "importing": "Đang nhập khẩu...", - "importToken": "Nhập mã thông báo", - "cancel": "Hủy bỏ", - "errorAutoDetect": "Không thể tự động phát hiện mã thông báo", - "errorAutoDetectFailed": "Tự động phát hiện mã thông báo không thành công", - "errorEnterToken": "Vui lòng nhập mã thông báo truy cập", - "errorImportFailed": "Nhập không thành công" + "machineIdPlaceholder": "Mã máy sẽ được tự động điền...", + "importing": "Đang nhập...", + "importToken": "Nhập token", + "cancel": "Hủy", + "errorAutoDetect": "Không thể tự động phát hiện token", + "errorAutoDetectFailed": "Tự động phát hiện token không thành công", + "errorEnterToken": "Vui lòng nhập token truy cập", + "errorImportFailed": "Nhập thất bại" }, "pricingModal": { "title": "Cấu hình giá", "loading": "Đang tải dữ liệu giá...", - "pricingRatesFormat": "Định dạng giá cước", - "ratesDescription": "Tất cả mức giá đều được tính bằng đô la trên một triệu mã thông báo ($/1 triệu mã thông báo). Ví dụ: Tỷ lệ đầu vào 2,50 có nghĩa là 2,50 USD trên 1.000.000 mã thông báo đầu vào.", - "model": "người mẫu", - "input": "đầu vào", - "output": "đầu ra", - "cached": "Đã lưu vào bộ nhớ đệm", - "reasoning": "Lý luận", - "cacheCreation": "Tạo bộ đệm", - "noPricingData": "Không có dữ liệu giá cả", + "pricingRatesFormat": "Định dạng mức giá", + "ratesDescription": "Tất cả mức giá đều được tính bằng đô la trên mỗi triệu token ($/1 triệu token). Ví dụ: Mức giá đầu vào là 2.50 nghĩa là $2.50 cho mỗi 1.000.000 token đầu vào.", + "model": "Mô hình", + "input": "Đầu vào", + "output": "Đầu ra", + "cached": "Đã lưu trong cache", + "reasoning": "Suy luận", + "cacheCreation": "Tạo cache", + "noPricingData": "Không có dữ liệu giá", "resetToDefaults": "Đặt lại về mặc định", - "cancel": "Hủy bỏ", + "cancel": "Hủy", "saving": "Đang lưu...", "saveChanges": "Lưu thay đổi", - "resetConfirm": "Đặt lại tất cả giá về mặc định? Điều này không thể hoàn tác được.", - "errorSaveFailed": "Không lưu được giá", + "resetConfirm": "Đặt lại tất cả giá về mặc định? Hành động này không thể hoàn tác.", + "errorSaveFailed": "Không thể lưu giá", "errorResetFailed": "Không thể đặt lại giá" }, "proxyRegistry": { - "title": "Title", - "description": "Description", - "importLegacy": "Import Legacy", - "bulkAssign": "Bulk Assign", - "addProxy": "Add Proxy", - "loading": "Loading", - "noProxies": "No Proxies", - "tableName": "Table Name", - "tableEndpoint": "Table Endpoint", - "tableStatus": "Table Status", - "tableHealth": "Table Health", - "tableUsage": "Table Usage", - "tableActions": "Table Actions", - "test": "Test", - "edit": "Edit", - "delete": "Delete", - "modalCreateTitle": "Modal Create Title", - "modalEditTitle": "Modal Edit Title", - "labelName": "Label Name", - "labelType": "loại", + "title": "Sổ đăng ký proxy", + "description": "Lưu trữ các proxy có thể tái sử dụng và theo dõi việc gán chúng.", + "importLegacy": "Nhập dữ liệu cũ", + "bulkAssign": "Gán hàng loạt", + "addProxy": "Thêm proxy", + "loading": "Đang tải các proxy...", + "noProxies": "Chưa có proxy nào được lưu.", + "tableName": "Tên", + "tableEndpoint": "Endpoint", + "tableStatus": "Trạng thái", + "tableHealth": "Trạng thái hoạt động (24h)", + "tableUsage": "Mức sử dụng", + "tableActions": "Hành động", + "test": "Kiểm tra", + "edit": "Chỉnh sửa", + "delete": "Xóa", + "modalCreateTitle": "Tạo proxy", + "modalEditTitle": "Chỉnh sửa proxy", + "labelName": "Tên", + "labelType": "Loại", "labelHost": "Máy chủ", - "labelPort": "Cảng", - "labelUsername": "Tên người dùng", + "labelPort": "Cổng", + "labelUsername": "Tên đăng nhập", "labelPassword": "Mật khẩu", "labelRegion": "Vùng", "labelStatus": "Trạng thái", "labelNotes": "Ghi chú", - "usernamePlaceholderEdit": "Để trống để giữ tên người dùng hiện tại", + "usernamePlaceholderEdit": "Để trống để giữ tên đăng nhập hiện tại", "passwordPlaceholderEdit": "Để trống để giữ mật khẩu hiện tại", - "statusActive": "Đang hoạt động", + "statusActive": "Hoạt động", "statusInactive": "Không hoạt động", - "cancel": "Hủy bỏ", + "cancel": "Hủy", "save": "Lưu", - "bulkModalTitle": "Phân công proxy số lượng lớn", + "bulkModalTitle": "Gán proxy hàng loạt", "bulkLabelScope": "Phạm vi", - "bulkLabelProxy": "ủy nhiệm", - "bulkClearAssignment": "(Xóa bài tập)", - "bulkLabelScopeIds": "ID phạm vi (được phân tách bằng dấu phẩy hoặc dòng mới)", - "bulkScopeIdsPlaceholder": "nhà cung cấp-openai,nhà cung cấp-anthropic", + "bulkLabelProxy": "Proxy", + "bulkClearAssignment": "(Xóa việc gán)", + "bulkLabelScopeIds": "ID phạm vi (phân tách bằng dấu phẩy hoặc dòng mới)", + "bulkScopeIdsPlaceholder": "provider-openai,provider-anthropic", "bulkApply": "Áp dụng", - "labelScope": "__MISSING__:Scope", - "labelProxy": "__MISSING__:Proxy", - "scopeGlobal": "__MISSING__:global", - "scopeProvider": "__MISSING__:provider", - "scopeAccount": "__MISSING__:account", - "scopeCombo": "__MISSING__:combo", - "bulkImportErrorMissingName": "Thiếu TÊN", - "bulkImportErrorMissingHost": "Thiếu máy chủ", - "bulkImportErrorInvalidPort": "PORT không hợp lệ (phải là 1-65535)", - "bulkImportErrorInvalidType": "LOẠI không hợp lệ (sử dụng http, https hoặc sock5)", - "bulkImportErrorInvalidStatus": "TÌNH TRẠNG không hợp lệ (sử dụng hoạt động hoặc không hoạt động)", - "errorLoadFailed": "Error Load Failed", - "errorNameHostRequired": "Error Name Host Required", - "errorSaveFailed": "Error Save Failed", - "errorDeleteFailed": "Error Delete Failed", - "errorForceDeleteConfirm": "Error Force Delete Confirm", - "errorMigrateFailed": "Error Migrate Failed", - "errorBulkFailed": "Error Bulk Failed", + "labelScope": "Phạm vi", + "labelProxy": "Proxy", + "scopeGlobal": "toàn cục", + "scopeProvider": "nhà cung cấp", + "scopeAccount": "tài khoản", + "scopeCombo": "combo", + "bulkImportErrorMissingName": "Thiếu NAME", + "bulkImportErrorMissingHost": "Thiếu HOST", + "bulkImportErrorInvalidPort": "PORT không hợp lệ (phải từ 1-65535)", + "bulkImportErrorInvalidType": "TYPE không hợp lệ (sử dụng http, https hoặc socks5)", + "bulkImportErrorInvalidStatus": "STATUS không hợp lệ (sử dụng active hoặc inactive)", + "errorLoadFailed": "Tải danh sách đăng ký proxy thất bại", + "errorNameHostRequired": "Tên và máy chủ là bắt buộc", + "errorSaveFailed": "Lưu proxy thất bại", + "errorDeleteFailed": "Xóa proxy thất bại", + "errorForceDeleteConfirm": "Proxy này vẫn đang được gán. Buộc xóa và gỡ bỏ tất cả các mục gán?", + "errorMigrateFailed": "Di chuyển cấu hình proxy cũ thất bại", + "errorBulkFailed": "Thực hiện gán số lượng lớn thất bại", "success": "✓", "failure": "✗", - "failed": "Failed", + "failed": "Thất bại", "successRate": "{rate}% thành công", "avgLatency": "trung bình {latency}ms", - "assignmentsCount": "{count} bài tập", - "noData": "No Data", + "assignmentsCount": "{count} lượt gán", + "noData": "—", "testSuccess": "✓ {ip}", "testLatency": "{latency}ms", "testFailure": "✗ {error}", - "bulkImport": "Nhập số lượng lớn", - "bulkImportTitle": "Proxy nhập số lượng lớn", - "bulkImportDescription": "Dán hồ sơ proxy bằng định dạng được phân cách bằng đường ống. Một proxy trên mỗi dòng. Các proxy hiện có (cùng máy chủ + cổng) sẽ được cập nhật.", + "bulkImport": "Nhập proxy hàng loạt", + "bulkImportTitle": "Nhập proxy hàng loạt", + "bulkImportDescription": "Dán hồ sơ proxy, mỗi hồ sơ trên một dòng. Các định dạng được hỗ trợ: phân tách bằng dấu gạch đứng (NAME|HOST|PORT|…), dạng viết tắt (ip:port, ip:port:user:pass, user:pass@ip:port, user:pass:ip:port, protocol://ip:port, protocol://user:pass@ip:port), hoặc chế độ tiêu đề giao thức (giao thức đơn thuần ở dòng đầu tiên sẽ áp dụng cho các dòng dạng viết tắt tiếp theo). Các proxy hiện có (cùng host + port) sẽ được cập nhật.", "bulkImportParse": "Phân tích cú pháp", "bulkImportImport": "Nhập {count} proxy", - "bulkImportImporting": "Đang nhập khẩu...", - "bulkImportParsed": "{count} proxy được phân tích cú pháp", - "bulkImportSkipped": "{count} dòng bị bỏ qua", + "bulkImportImporting": "Đang nhập...", + "bulkImportParsed": "Đã phân tích cú pháp {count} proxy", + "bulkImportSkipped": "Đã bỏ qua {count} dòng", "bulkImportParseErrors": "{count} lỗi", - "bulkImportNoValidEntries": "Không tìm thấy mục hợp lệ. Hãy kiểm tra định dạng và thử lại.", - "bulkImportSuccess": "Quá trình nhập hoàn tất: {created} đã tạo, {updated} đã cập nhật, {failed} không thành công", + "bulkImportNoValidEntries": "Không tìm thấy mục hợp lệ nào. Hãy kiểm tra định dạng và thử lại.", + "bulkImportSuccess": "Nhập hoàn tất: {created} đã tạo, {updated} đã cập nhật, {failed} thất bại", "bulkImportErrorLine": "Dòng {line}: {reason}", "bulkImportMaxExceeded": "Tối đa 100 proxy cho mỗi lần nhập", "bulkImportPreview": "Xem trước", - "clearAssignment": "(phân công rõ ràng)", - "bulkProxyAssignment": "Phân công proxy số lượng lớn" + "clearAssignment": "(xóa gán)", + "bulkProxyAssignment": "Gán proxy hàng loạt", + "labelFamily": "IP family", + "familyAuto": "Auto (dual-stack)", + "familyIpv4": "IPv4 only", + "familyIpv6": "IPv6 only", + "familyHint": "Egress address family. Auto keeps dual-stack; IPv4/IPv6 pin this proxy to that family (prevents a v4 leak under an IPv6-only proxy).", + "repair": "Repair", + "relayAuthMissing": "auth missing", + "relayRepairTooltip": "Recover relay auth in place. If the token is unrecoverable (e.g. after a STORAGE_ENCRYPTION_KEY rotation), redeploy the relay instead.", + "relayRepairRedeployRequired": "Relay auth is unrecoverable — redeploy the relay to write a fresh token.", + "relayRepairFailed": "Relay repair failed", + "relayRepairError": "repair failed", + "relayProbeSummary": "Relay probes: {alive}/{tested} alive", + "testAll": "Test All", + "errorTestFailed": "Failed to test proxies", + "batchSelectedCount": "{count} selected", + "batchDeleteSelected": "Delete {count} selected", + "batchActivateSelected": "Enable {count} selected", + "testPassed": "✓ OK", + "close": "Close", + "managePool": "Manage Pool", + "poolTitle": "Proxy Pool & Rotation", + "poolDescription": "Attach multiple proxies to a scope and rotate egress IPs across them. A scope with a single proxy behaves exactly like a plain assignment.", + "poolScopeIdLabel": "Scope ID", + "poolScopeIdPlaceholder": "provider id / connection id / combo id", + "poolScopeIdRequired": "A scope ID is required for provider, account, or combo scope.", + "poolLoad": "Load Pool", + "poolLoadFailed": "Failed to load the proxy pool", + "poolStrategyLabel": "Rotation strategy", + "poolStrategyHint": "round-robin cycles members in order; random picks uniformly; sticky holds one member for a window; latency-optimized picks the fastest based on logs.", + "poolStrategyFailed": "Failed to update the rotation strategy", + "strategyRoundRobin": "Round-robin", + "strategyRandom": "Random", + "strategySticky": "Sticky", + "strategyLatency": "Latency-optimized", + "poolMembersLabel": "Pool members ({count})", + "poolNoMembers": "No proxies in this pool yet.", + "poolRemove": "Remove", + "poolRemoveFailed": "Failed to remove the proxy from the pool", + "poolAddLabel": "Add a proxy", + "poolAddMember": "Add", + "poolAddFailed": "Failed to add the proxy to the pool", + "poolSelectProxy": "Select a proxy…", + "poolSaveFailed": "Failed to save pool assignment" }, "playground": { - "title": "Title", - "description": "Description", + "title": "Khu thử nghiệm mô hình", + "description": "Thử nghiệm bất kỳ mô hình nào trực tiếp từ bảng điều khiển. Chọn nhà cung cấp, mô hình và loại endpoint, sau đó gửi một yêu cầu để xem phản hồi thô.", "endpoint": "Endpoint", - "provider": "Provider", - "model": "Model", - "accountKey": "Account Key", + "provider": "Nhà cung cấp", + "model": "Mô hình", + "accountKey": "Tài khoản / Khóa", "autoAccounts": "Tự động ({count} tài khoản)", - "noAccounts": "No Accounts", - "send": "Send", - "cancel": "Cancel", - "audioFile": "Audio File", - "attachImages": "Attach Images", - "multipartFormData": "Multipart Form Data", - "upToImages": "Up To Images", - "selectAudioFile": "Select Audio File", - "clearAll": "Clear All", - "request": "Request", - "response": "Response", - "transcription": "Transcription", - "copy": "Copy", - "resetToDefault": "Reset To Default", - "downloadAudio": "Download Audio", - "copyText": "Copy Text", - "transcriptionHint": "Transcription Hint", + "noAccounts": "Không có tài khoản", + "send": "Gửi", + "cancel": "Hủy", + "audioFile": "Tập tin âm thanh", + "attachImages": "Đính kèm hình ảnh (Vision)", + "multipartFormData": "multipart/form-data", + "upToImages": "Tối đa 4 hình ảnh", + "selectAudioFile": "Chọn tập tin âm thanh để phiên âm (mp3, wav, m4a, ogg, flac…)", + "clearAll": "Xóa tất cả", + "request": "Yêu cầu", + "response": "Phản hồi", + "transcription": "Phiên âm", + "copy": "Sao chép", + "resetToDefault": "Đặt lại về mặc định", + "downloadAudio": "Tải xuống âm thanh", + "copyText": "Sao chép văn bản", + "transcriptionHint": "Chuyển âm thanh thành văn bản sử dụng multipart/form-data. Hãy tải tệp âm thanh lên ở trên — phần JSON bên dưới kiểm soát các tham số bổ sung (mô hình, ngôn ngữ).", "imagesGenerated": "Đã tạo {count} hình ảnh", - "generatedImage": "Hình ảnh được tạo {index}", - "save": "Save", + "generatedImage": "Hình ảnh {index} đã được tạo", + "save": "Lưu", "endpointOptions": { - "chat": "Chat", - "responses": "Responses", - "images": "Images", + "chat": "Chat completions", + "responses": "Phản hồi", + "images": "Tạo hình ảnh", "embeddings": "Embeddings", - "speech": "Speech", - "transcription": "Transcription", - "video": "Video", - "music": "Music", - "rerank": "Rerank", - "search": "Search" + "speech": "Chuyển văn bản thành giọng nói", + "transcription": "Chuyển âm thanh thành văn bản", + "video": "Tạo video", + "music": "Tạo nhạc", + "rerank": "Xếp hạng lại", + "search": "Tìm kiếm web" }, - "conversationalChat": "Trò chuyện đàm thoại", + "conversationalChat": "Trò chuyện đa lượt", "clearChat": "Xóa cuộc trò chuyện", - "typeMessagePlaceholder": "Nhập tin nhắn... (Shift+Enter cho dòng mới)", - "tabChat": "Chat", - "tabCompare": "Compare", + "typeMessagePlaceholder": "Nhập tin nhắn... (Shift+Enter để xuống dòng)", + "tabChat": "Trò chuyện", + "tabCompare": "So sánh", "tabApi": "API", - "tabBuild": "Build", - "configPane": "Config", - "systemPrompt": "System prompt", - "systemPromptPlaceholder": "You are a helpful assistant.", - "modelPlaceholder": "e.g. openai/gpt-4o", + "tabBuild": "Xây dựng", + "configPane": "Cấu hình", + "systemPrompt": "Prompt hệ thống", + "systemPromptPlaceholder": "Bạn là một trợ lý hữu ích.", + "modelPlaceholder": "Ví dụ: openai/gpt-4o", "endpointLabel": "Endpoint", - "parametersLabel": "Parameters", - "collapseConfig": "Collapse config pane", - "expandConfig": "Expand config pane", - "temperature": "Temperature", - "maxTokens": "Max tokens", + "parametersLabel": "Tham số", + "collapseConfig": "Thu gọn bảng cấu hình", + "expandConfig": "Mở rộng bảng cấu hình", + "temperature": "Nhiệt độ", + "maxTokens": "Số token tối đa", "topP": "Top-p", - "presencePenalty": "Presence penalty", - "frequencyPenalty": "Frequency penalty", - "seedPlaceholder": "Random (leave empty)", - "presetsLabel": "Presets", - "loadPreset": "Load preset", - "savePreset": "Save preset", - "noPresets": "No presets", - "presetNamePlaceholder": "Preset name", - "savingPreset": "Saving…", - "nameRequired": "Name is required", - "failedToSavePreset": "Failed to save preset", - "improvePrompt": "Improve prompt", - "improvingPrompt": "Improving…", - "improvePromptTitle": "Improve your prompt with AI", - "setModelFirst": "Set a model first", - "improveQuotaWarning": "This will consume quota from the model configured in Config.", - "improveConfirm": "Improve", - "exportCode": "Export code", - "exportCodeTitle": "Export Code", - "noStateToExport": "No playground state available to export.", - "copyCode": "Copy", - "copiedCode": "Copied!", - "addModel": "+ Add model", - "runAll": "Run all", - "cancelAll": "Cancel all", - "maxColumnsReached": "Maximum {max} columns", - "modelPlaceholderCompare": "Model (Cmd+K)…", + "presencePenalty": "Mức phạt hiện diện", + "frequencyPenalty": "Mức phạt tần suất", + "seedPlaceholder": "Ngẫu nhiên (để trống)", + "presetsLabel": "Cài đặt sẵn", + "loadPreset": "Tải cài đặt sẵn", + "savePreset": "Lưu cài đặt sẵn", + "noPresets": "Không có cài đặt sẵn nào", + "presetNamePlaceholder": "Tên cài đặt sẵn", + "savingPreset": "Đang lưu…", + "nameRequired": "Yêu cầu nhập tên", + "failedToSavePreset": "Không thể lưu cài đặt sẵn", + "improvePrompt": "Cải thiện prompt", + "improvingPrompt": "Đang cải thiện…", + "improvePromptTitle": "Cải thiện prompt của bạn bằng AI", + "setModelFirst": "Hãy thiết lập một mô hình trước", + "improveQuotaWarning": "Hành động này sẽ tiêu thụ hạn mức từ mô hình được định cấu hình trong mục Cấu hình.", + "improveConfirm": "Cải thiện", + "exportCode": "Xuất mã", + "exportCodeTitle": "Xuất mã", + "noStateToExport": "Không có trạng thái khu thử nghiệm nào để xuất.", + "copyCode": "Sao chép", + "copiedCode": "Đã sao chép!", + "addModel": "+ Thêm mô hình", + "runAll": "Chạy tất cả", + "cancelAll": "Hủy tất cả", + "maxColumnsReached": "Tối đa {max} cột", + "modelPlaceholderCompare": "Mô hình (Cmd+K)…", "ttft": "TTFT", "tps": "TPS", - "metricsDisclaimer": "client-side estimate", - "tokensLabel": "Tokens", - "costLabel": "Cost", - "costEstimated": "(estimated)", - "toolsLabel": "Tools", - "addTool": "Add tool", - "toolNamePlaceholder": "Function name", - "toolDescPlaceholder": "Description (optional)", - "toolParamsInvalid": "Parameters must be valid JSON", - "structuredOutputLabel": "Structured Output", - "enableJsonMode": "Enable JSON mode", - "disableJsonMode": "Disable JSON mode", - "invalidJson": "Invalid JSON", - "running": "Running…", - "runLabel": "Run", - "enterToolResult": "Enter tool result…" + "metricsDisclaimer": "ước tính phía máy khách", + "tokensLabel": "Token", + "costLabel": "Chi phí", + "costEstimated": "(ước tính)", + "toolsLabel": "Công cụ", + "addTool": "Thêm công cụ", + "toolNamePlaceholder": "Tên hàm", + "toolDescPlaceholder": "Mô tả (tùy chọn)", + "toolParamsInvalid": "Các tham số phải là JSON hợp lệ", + "structuredOutputLabel": "Đầu ra cấu trúc", + "enableJsonMode": "Bật chế độ JSON", + "disableJsonMode": "Tắt chế độ JSON", + "invalidJson": "JSON không hợp lệ", + "running": "Đang chạy…", + "runLabel": "Chạy", + "enterToolResult": "Nhập kết quả công cụ…", + "reasoningLabel": "Reasoning", + "thinking": "Thinking", + "effort": "Effort", + "effortDefault": "Default", + "exportShort": "Export", + "closeExportModal": "Close export modal", + "close": "Close", + "exportRealKeyWarning": "Security warning: export blocked — a real API key was detected in the output. Please reset your API key and try again.", + "placeholderHintPrefix": "Replace", + "placeholderHintSuffix": "with your actual API key, or set it as an environment variable.", + "copyLangCode": "Copy {language} code", + "loadingPresets": "Loading…", + "loadPresetPlaceholder": "Load preset…", + "build": { + "step1Label": "What to test?", + "step2Label": "Configure", + "step3Label": "Run", + "step1Title": "What do you want to test?", + "step1Subtitle": "Choose the capability you want to explore in this session.", + "step2Title": "Configure", + "step2Subtitle": "Set up the tools or JSON schema that will be used in the request.", + "step3Title": "Run", + "modeToolsTitle": "Tools", + "modeToolsDesc": "Test function calling — define tools and see how the model invokes them.", + "modeJsonTitle": "JSON", + "modeJsonDesc": "Test structured output — constrain the response to a JSON schema.", + "modeBothTitle": "Tools + JSON", + "modeBothDesc": "Combine function calling and structured output in a single request.", + "backButton": "Back", + "nextButton": "Next", + "runButton": "Run", + "promptPlaceholder": "Enter your message… (Enter to send, Shift+Enter for newline)" + } }, "miniPlayground": { - "endpoint": "__MISSING__:Endpoint", - "apiKey": "__MISSING__:API Key", - "model": "__MISSING__:Model", - "voice": "__MISSING__:Voice", - "speed": "__MISSING__:Speed", - "input": "__MISSING__:Input", - "url": "__MISSING__:URL", - "format": "__MISSING__:Format", - "depth": "__MISSING__:Depth", - "copyCurl": "__MISSING__:Copy cURL", - "copied": "__MISSING__:Copied!", - "run": "__MISSING__:Run", - "running": "__MISSING__:Running...", - "response": "__MISSING__:Response", - "tunnel": "__MISSING__:Tunnel", - "send": "__MISSING__:Send", - "selectKey": "__MISSING__:Select key", - "testLabel": "__MISSING__:Test", - "expandTest": "__MISSING__:Expand test", - "collapseTest": "__MISSING__:Collapse test", - "revealKey": "__MISSING__:Reveal key", - "hideKey": "__MISSING__:Hide key", - "download": "__MISSING__:Download", - "play": "__MISSING__:Play", - "query": "__MISSING__:Query", - "numResults": "__MISSING__:Max results", - "prompt": "__MISSING__:Prompt", - "size": "__MISSING__:Size", - "duration": "__MISSING__:Duration", - "question": "__MISSING__:Question", - "audioFile": "__MISSING__:Audio file", - "noKeysFound": "__MISSING__:No API keys found. Add one in the Keys section.", - "exampleLabel": "__MISSING__:Example", - "latency": "__MISSING__:{ms}ms", - "statsLine": "__MISSING__:{ms}ms · {tokensIn} in / {tokensOut} out tokens" + "endpoint": "Endpoint", + "apiKey": "Khóa API", + "model": "Mô hình", + "voice": "Giọng nói", + "speed": "Tốc độ", + "input": "Đầu vào", + "url": "URL", + "format": "Định dạng", + "depth": "Độ sâu", + "copyCurl": "Sao chép cURL", + "copied": "Đã sao chép!", + "run": "Chạy", + "running": "Đang chạy...", + "response": "Phản hồi", + "tunnel": "Đường hầm", + "send": "Gửi", + "selectKey": "Chọn khóa", + "testLabel": "Kiểm thử", + "expandTest": "Mở rộng kiểm thử", + "collapseTest": "Thu gọn kiểm thử", + "revealKey": "Hiển thị khóa", + "hideKey": "Ẩn khóa", + "download": "Tải xuống", + "play": "Phát", + "query": "Truy vấn", + "numResults": "Số kết quả tối đa", + "prompt": "Prompt", + "size": "Kích thước", + "duration": "Thời lượng", + "question": "Câu hỏi", + "audioFile": "Tệp âm thanh", + "noKeysFound": "Không tìm thấy khóa API nào. Hãy thêm một khóa trong phần Khóa.", + "exampleLabel": "Ví dụ", + "latency": "{ms}ms", + "statsLine": "{ms}ms · {tokensIn} token vào / {tokensOut} token ra" }, "requestLogger": { - "recording": "Recording", - "paused": "Paused", - "pipelineLogsOn": "Pipeline logs on", - "pipelineLogsOff": "Pipeline logs off", - "updatingPipelineLogs": "Updating pipeline logs...", - "updatePipelineFailed": "Failed to update pipeline logging", - "capturePipeline": "Capture pipeline payloads for new requests", - "searchPlaceholder": "Search models, providers, accounts, API keys, combos...", - "allProviders": "All providers", - "allModels": "All models", - "allAccounts": "All accounts", - "allApiKeys": "All API keys", - "total": "Total", - "ok": "Success", - "err": "Error", + "recording": "Đang ghi", + "paused": "Đã tạm dừng", + "pipelineLogsOn": "Bật nhật ký pipeline", + "pipelineLogsOff": "Tắt nhật ký pipeline", + "updatingPipelineLogs": "Đang cập nhật nhật ký pipeline...", + "updatePipelineFailed": "Không thể cập nhật tính năng ghi nhật ký pipeline", + "capturePipeline": "Ghi lại dữ liệu tải của pipeline cho các yêu cầu mới", + "searchPlaceholder": "Tìm kiếm mô hình, nhà cung cấp, tài khoản, khóa API, tổ hợp...", + "allProviders": "Tất cả nhà cung cấp", + "allModels": "Tất cả mô hình", + "allAccounts": "Tất cả tài khoản", + "allApiKeys": "Tất cả khóa API", + "total": "Tổng cộng", + "ok": "Thành công", + "err": "Lỗi", "combo": "Combo", - "keys": "Keys", - "shown": "Shown", - "sortNewest": "Newest", - "sortOldest": "Oldest", - "sortTokensDesc": "Tokens ↓", - "sortTokensAsc": "Tokens ↑", - "sortDurationDesc": "Duration ↓", - "sortDurationAsc": "Duration ↑", - "sortStatusDesc": "Status ↓", - "sortStatusAsc": "Status ↑", - "sortModelAsc": "Model A-Z", - "sortModelDesc": "Model Z-A", - "sortLogs": "Sort logs", - "refresh": "Refresh", - "columnsLabel": "Columns", + "keys": "Khóa", + "shown": "Đang hiển thị", + "sortNewest": "Mới nhất", + "sortOldest": "Cũ nhất", + "sortTokensDesc": "Token ↓", + "sortTokensAsc": "Token ↑", + "sortDurationDesc": "Thời lượng ↓", + "sortDurationAsc": "Thời lượng ↑", + "sortStatusDesc": "Trạng thái ↓", + "sortStatusAsc": "Trạng thái ↑", + "sortModelAsc": "Mô hình A-Z", + "sortModelDesc": "Mô hình Z-A", + "sortLogs": "Sắp xếp nhật ký", + "refresh": "Làm mới", + "columnsLabel": "Cột", "cacheSem": "SEM", "cacheUp": "UP", - "semantic": "Semantic", - "upstream": "Upstream", - "semanticCacheHit": "Semantic cache hit (served by OmniRoute)", - "upstreamResponse": "Upstream provider response", - "noApiKey": "No API key", - "requestedRoutedTitle": "Requested {requested}, routed as {routed}", + "semantic": "Ngữ nghĩa", + "upstream": "Thượng nguồn", + "semanticCacheHit": "Có kết quả khớp trong cache ngữ nghĩa (do OmniRoute phục vụ)", + "upstreamResponse": "Phản hồi từ nhà cung cấp thượng nguồn", + "noApiKey": "Không có khóa API", + "requestedRoutedTitle": "Yêu cầu {requested}, được định tuyến tới {routed}", "statusFilters": { - "all": "All", - "error": "Errors", - "success": "Success", + "all": "Tất cả", + "error": "Lỗi", + "success": "Thành công", "combo": "Combo" }, "columns": { - "status": "Status", - "cacheSource": "Cache Source", - "model": "Model", - "requested": "Requested", - "provider": "Provider", - "protocol": "Request Protocol", - "account": "Account", - "apiKey": "API Key", + "status": "Trạng thái", + "cacheSource": "Nguồn cache", + "model": "Mô hình", + "requested": "Đã yêu cầu", + "provider": "Nhà cung cấp", + "protocol": "Giao thức yêu cầu", + "account": "Tài khoản", + "apiKey": "Khóa API", "combo": "Combo", - "tokens": "Tokens", - "compressed": "nén", + "tokens": "Token", + "compressed": "Nén", "tps": "TPS", - "duration": "Duration", - "time": "Time" + "duration": "Thời lượng", + "time": "Thời gian" }, - "loadingLogs": "Loading logs...", - "noLogs": "No logs yet. Make some API calls to see them here.", - "noMatchingLogs": "No logs matching current filters.", - "callLogsInfo": "Call logs are also saved as JSON files to {dataDir} and rotated based on {retentionDays} and {maxEntries}." + "loadingLogs": "Đang tải nhật ký...", + "noLogs": "Chưa có nhật ký nào. Hãy thực hiện một số cuộc gọi API để xem chúng ở đây.", + "noMatchingLogs": "Không có nhật ký nào khớp với các bộ lọc hiện tại.", + "callLogsInfo": "Nhật ký cuộc gọi cũng được lưu dưới dạng tệp JSON tại {dataDir} và được luân chuyển dựa trên {retentionDays} và {maxEntries}.", + "loadMore": "Load More", + "loadingMore": "Loading more..." }, "proxyLogger": { - "filterAll": "All", - "filterErrors": "Errors", - "filterSuccess": "Success", - "filterTimeout": "Timeout", - "colStatus": "Status", + "filterAll": "Tất cả", + "filterErrors": "Lỗi", + "filterSuccess": "Thành công", + "filterTimeout": "Hết thời gian chờ", + "colStatus": "Trạng thái", "colProxy": "Proxy", "colTls": "TLS", - "colType": "Type", - "colLevel": "Level", - "colProvider": "Provider", - "colTarget": "Target", - "colLatency": "Latency", - "colClientIp": "Client IP", - "colTime": "Time", - "recording": "Recording", - "paused": "Paused", - "searchPlaceholder": "Search host, provider, target, IP...", - "allTypes": "All Types", - "allLevels": "All Levels", - "allProviders": "All Providers", - "total": "total", + "colType": "Loại", + "colLevel": "Cấp độ", + "colProvider": "Nhà cung cấp", + "colTarget": "Đích", + "colLatency": "Độ trễ", + "colClientIp": "IP máy khách", + "colTime": "Thời gian", + "recording": "Đang ghi", + "paused": "Đã tạm dừng", + "searchPlaceholder": "Tìm kiếm máy chủ, nhà cung cấp, đích, IP...", + "allTypes": "Tất cả các loại", + "allLevels": "Tất cả các cấp", + "allProviders": "Tất cả nhà cung cấp", + "total": "tổng cộng", "ok": "OK", "err": "ERR", "timeoutShort": "TMO", - "direct": "direct", - "newest": "Newest", - "oldest": "Oldest", - "latencyDesc": "Latency ↓", - "latencyAsc": "Latency ↑", - "refresh": "Refresh", - "columns": "Columns", - "loadingProxyLogs": "Loading proxy logs...", - "noProxyLogs": "No proxy logs yet. Configure proxies and make API calls to see them here.", - "noMatchingLogs": "No logs match the current filters.", - "tlsFingerprint": "Chrome 124 TLS Fingerprint" + "direct": "trực tiếp", + "newest": "Mới nhất", + "oldest": "Cũ nhất", + "latencyDesc": "Độ trễ ↓", + "latencyAsc": "Độ trễ ↑", + "refresh": "Làm mới", + "columns": "Cột", + "loadingProxyLogs": "Đang tải nhật ký proxy...", + "noProxyLogs": "Chưa có nhật ký proxy. Cấu hình proxy và thực hiện các cuộc gọi API để xem chúng ở đây.", + "noMatchingLogs": "Không có nhật ký nào khớp với bộ lọc hiện tại.", + "tlsFingerprint": "Dấu vân tay TLS Chrome 124", + "colPublicIp": "Public IP" }, "endpointOptions": { - "speech": "Speech", - "search": "Search", - "images": "Images", - "chat": "Chat", - "music": "Music", - "responses": "Responses", - "rerank": "Rerank", + "speech": "Giọng nói", + "search": "Tìm kiếm", + "images": "Hình ảnh", + "chat": "Trò chuyện", + "music": "Âm nhạc", + "responses": "Phản hồi", + "rerank": "Xếp hạng lại", "video": "Video", - "embeddings": "Embeddings", - "transcription": "Transcription" + "embeddings": "Biểu diễn nhúng", + "transcription": "Phiên âm" }, "toolDescriptions": { "cline": "Cline", @@ -7492,160 +8495,250 @@ "kilo": "Kilo" }, "runtime": { - "title": "Runtime", - "description": "Realtime observability — 3-layer resilience + sessions + quota alerts", - "pause": "Pause", - "resume": "Resume", - "refreshNow": "Refresh now", - "kpiSessions": "Sessions", - "kpiCircuits": "Circuits", - "kpiCooldowns": "Cooldowns", - "kpiLockouts": "Lockouts", - "hintStickyBound": "{count} sticky-bound", - "hintRecovering": "{count} recovering", - "hintAllHealthy": "all healthy", - "hintOpen": "open", - "hintConnsCooling": "connections cooling", - "hintModelsBlocked": "models blocked", - "resilienceTitle": "3-Layer Resilience", - "resilienceSubtitle": "Mirrors the documented resilience model", - "providersHealthy": "{percent}% providers healthy", - "layer": "Layer {n}", - "layer1Title": "Provider Circuit Breakers", - "layer1Desc": "Stop traffic to providers failing at the upstream level", - "layer2Title": "Connection Cooldowns", - "layer2Desc": "Skip one bad account/key; other connections keep serving", - "layer3Title": "Model Lockouts", - "layer3Desc": "Per-model rate-limit locks; same connection still serves other models", - "badgeAffectedOf": "{affected} of {total} affected", - "badgeCooling": "{count} cooling", - "badgeLocked": "{count} locked", - "emptyCircuits": "No circuit breakers active yet", - "emptyCooldowns": "No connection cooldowns active", - "emptyLockouts": "No model lockouts", - "moreCooldowns": "+{count} more cooldowns", - "moreLockouts": "+{count} more lockouts", - "feedTitle": "Live Feed", - "feedSubtitle": "Last {count} events", - "feedFilterAll": "All", - "feedFilterCircuits": "Circuits", - "feedFilterCooldowns": "Cooldowns", - "feedFilterLockouts": "Lockouts", - "feedFilterSessions": "Sessions", - "feedFilterQuotas": "Quotas", - "feedClear": "Clear", - "feedEmptyWaiting": "Waiting for events... (polled every 5s)", - "feedEmptyFiltered": "No events match this filter", - "sessionsTitle": "Active Sessions", - "sessionsSubtitle": "Sticky-bound request fingerprints (live)", - "sessionsActive": "{count} active", - "sessionsEmptyTitle": "No active sessions", - "sessionsEmptyHint": "Sessions appear as requests flow through the proxy", - "tblSession": "Session", - "tblAge": "Age", - "tblIdle": "Idle", - "tblReqs": "Reqs", - "tblBoundTo": "Bound to", - "topApiKeys": "Top API keys", - "quotaMonitorsTitle": "Quota Monitors", - "quotaMonitorsSubtitle": "Live quota state per account window", - "openQuota": "Open Quota", - "allQuotasHealthy": "All quotas healthy", - "statusExhausted": "EXHAUSTED", - "statusAlerting": "ALERTING", - "statusError": "ERROR", - "moreSuffix": "+{count} more" + "title": "Thời gian chạy", + "description": "Khả năng giám sát theo thời gian thực — khả năng chống chịu 3 lớp + phiên + cảnh báo hạn ngạch", + "pause": "Tạm dừng", + "resume": "Tiếp tục", + "refreshNow": "Làm mới ngay", + "kpiSessions": "Phiên", + "kpiCircuits": "Bộ ngắt mạch", + "kpiCooldowns": "Thời gian chờ", + "kpiLockouts": "Khóa chặn", + "hintStickyBound": "{count} được liên kết cố định", + "hintRecovering": "{count} đang phục hồi", + "hintAllHealthy": "tất cả đều hoạt động bình thường", + "hintOpen": "mở", + "hintConnsCooling": "kết nối đang trong thời gian chờ", + "hintModelsBlocked": "mô hình bị chặn", + "resilienceTitle": "Khả năng chống chịu 3 lớp", + "resilienceSubtitle": "Phản ánh mô hình khả năng chống chịu đã được tài liệu hóa", + "providersHealthy": "{percent}% nhà cung cấp hoạt động bình thường", + "layer": "Lớp {n}", + "layer1Title": "Bộ ngắt mạch của nhà cung cấp", + "layer1Desc": "Dừng lưu lượng truy cập đến các nhà cung cấp gặp lỗi ở cấp thượng nguồn", + "layer2Title": "Thời gian chờ kết nối", + "layer2Desc": "Bỏ qua một tài khoản/khóa bị lỗi; các kết nối khác vẫn tiếp tục xử lý yêu cầu", + "layer3Title": "Khóa chặn mô hình", + "layer3Desc": "Khóa giới hạn tốc độ theo từng mô hình; cùng một kết nối vẫn xử lý các mô hình khác", + "badgeAffectedOf": "{affected}/{total} bị ảnh hưởng", + "badgeCooling": "{count} đang trong thời gian chờ", + "badgeLocked": "{count} bị khóa chặn", + "emptyCircuits": "Chưa có trình ngắt mạch nào hoạt động", + "emptyCooldowns": "Không có kết nối nào đang trong thời gian chờ", + "emptyLockouts": "Không có khóa chặn mô hình nào", + "moreCooldowns": "+{count} thời gian chờ khác", + "moreLockouts": "+{count} khóa chặn khác", + "feedTitle": "Luồng trực tiếp", + "feedSubtitle": "{count} sự kiện gần nhất", + "feedFilterAll": "Tất cả", + "feedFilterCircuits": "Bộ ngắt mạch", + "feedFilterCooldowns": "Thời gian chờ", + "feedFilterLockouts": "Khóa chặn", + "feedFilterSessions": "Phiên", + "feedFilterQuotas": "Hạn ngạch", + "feedClear": "Xóa", + "feedEmptyWaiting": "Đang chờ sự kiện... (được thăm dò mỗi 5 giây)", + "feedEmptyFiltered": "Không có sự kiện nào khớp với bộ lọc này", + "sessionsTitle": "Phiên hoạt động", + "sessionsSubtitle": "Dấu vân tay yêu cầu được liên kết cố định (trực tiếp)", + "sessionsActive": "{count} hoạt động", + "sessionsEmptyTitle": "Không có phiên hoạt động nào", + "sessionsEmptyHint": "Các phiên sẽ xuất hiện khi các yêu cầu đi qua proxy", + "tblSession": "Phiên", + "tblAge": "Thời gian tồn tại", + "tblIdle": "Không hoạt động", + "tblReqs": "Yêu cầu", + "tblBoundTo": "Liên kết với", + "topApiKeys": "Các khóa API hàng đầu", + "quotaMonitorsTitle": "Trình giám sát hạn ngạch", + "quotaMonitorsSubtitle": "Trạng thái hạn ngạch trực tiếp theo từng khoảng thời gian của tài khoản", + "openQuota": "Mở hạn ngạch", + "allQuotasHealthy": "Tất cả hạn ngạch hoạt động tốt", + "statusExhausted": "ĐÃ CẠN KIỆT", + "statusAlerting": "ĐANG CẢNH BÁO", + "statusError": "LỖI", + "moreSuffix": "+{count} nữa" }, "quotaShare": { - "title": "Quota Sharing", - "description": "Share provider quotas across API keys with % limits", - "newPool": "New pool", - "betaTitle": "Beta — UI preview.", - "betaDescription": "Configuration is saved in localStorage (not yet persisted on the server). Per-request cap enforcement is not yet wired into the proxy pipeline. This screen lets you design and visualize the quota split; real enforcement will land in a future iteration with DB persistence and upstream call interception.", - "kpiActivePools": "Active pools", - "kpiKeysAllocated": "Keys allocated", - "kpiAvgUnallocated": "Avg unallocated", - "kpiProvidersWithQuota": "Providers w/ quota", - "emptyTitle": "No pools configured", - "emptyDescription": "Create a pool to assign API keys to share a provider's quota window with % allocations.", - "loading": "Loading…", - "removePool": "Remove pool", - "removeConfirm": "Remove this pool?", - "pool": "Pool", - "used": "used", - "allocationsCount": "Allocations ({count})", - "allocatedFree": "{allocated}% allocated · {free}% free", - "noAllocations": "No keys allocated yet", - "capLabel": "cap {value}", - "notTrackedYet": "(not tracked yet)", - "policy": "Policy", - "policyHard": "hard", - "policySoft": "soft", - "policyBurst": "burst", - "policyHardHint": "Block when key exhausts allocation", - "policySoftHint": "Allow overflow, alert only", - "policyBurstHint": "Allow burst into free pool", - "editAllocations": "Edit allocations", - "newPoolTitle": "New quota pool", - "providerConnection": "Provider connection (account)", - "selectConnection": "Select a connection…", - "noEligibleConnections": "No connections with quota data. Refresh from /dashboard/quota first.", - "quotaWindow": "Quota window", - "selectWindow": "Select a window…", - "alreadyUsedSuffix": "(already used)", - "windowReset": "Reset", - "duplicatePoolError": "A pool for this connection + window already exists", - "cancel": "Cancel", - "createPool": "Create pool", - "editTitle": "Edit allocations", - "noKeysAdded": "No keys allocated. Add one below.", - "totalLabel": "Total: {percent}%", - "totalExceeded": "⚠ exceeds 100%", - "addKey": "+ Add key…", - "equalSplit": "Equal split", - "save": "Save allocations", - "betaPreviewLabel": "Beta - xem trước giao diện người dùng.", + "title": "Chia sẻ hạn ngạch", + "description": "Chia sẻ hạn ngạch của nhà cung cấp giữa các khóa API với giới hạn %", + "newPool": "Nhóm mới", + "betaTitle": "Beta", + "betaDescription": "Cấu hình được lưu trong localStorage (chưa được lưu lâu dài trên máy chủ). Việc thực thi giới hạn cho từng yêu cầu chưa được tích hợp vào quy trình xử lý của proxy. Màn hình này cho phép bạn thiết kế và trực quan hóa việc phân chia hạn ngạch; việc áp dụng thực tế sẽ được triển khai trong phiên bản tương lai với tính năng lưu trữ DB và chặn các lệnh gọi upstream.", + "kpiActivePools": "Nhóm đang hoạt động", + "kpiKeysAllocated": "Các khóa API đã phân bổ", + "kpiAvgUnallocated": "Tỷ lệ chưa phân bổ trung bình", + "kpiProvidersWithQuota": "Nhà cung cấp có hạn ngạch", + "emptyTitle": "Chưa cấu hình nhóm nào", + "emptyDescription": "Tạo một nhóm để gán các khóa API nhằm chia sẻ khung hạn ngạch của nhà cung cấp với tỷ lệ phân bổ %.", + "loading": "Đang tải…", + "removePool": "Xóa nhóm", + "removeConfirm": "Xóa nhóm này?", + "pool": "Nhóm", + "used": "đã dùng", + "allocationsCount": "Phân bổ ({count})", + "allocatedFree": "{allocated}% đã phân bổ · {free}% còn trống", + "noAllocations": "Chưa có khóa API nào được phân bổ", + "capLabel": "giới hạn {value}", + "notTrackedYet": "(chưa được theo dõi)", + "policy": "Chính sách", + "policyHard": "cứng", + "policySoft": "mềm", + "policyBurst": "bùng phát", + "policyHardHint": "Chặn khi khóa API sử dụng hết phần được phân bổ", + "policySoftHint": "Cho phép vượt quá, chỉ cảnh báo", + "policyBurstHint": "Cho phép tăng đột biến trong phần hạn ngạch còn trống", + "editAllocations": "Chỉnh sửa phân bổ", + "newPoolTitle": "Nhóm hạn ngạch mới", + "providerConnection": "Kết nối nhà cung cấp (tài khoản)", + "selectConnection": "Chọn một kết nối…", + "noEligibleConnections": "Không có kết nối nào có dữ liệu hạn ngạch. Vui lòng làm mới từ /dashboard/quota trước.", + "quotaWindow": "Khung hạn ngạch", + "selectWindow": "Chọn một khung hạn ngạch…", + "alreadyUsedSuffix": "(đã được sử dụng)", + "windowReset": "Đặt lại", + "duplicatePoolError": "Nhóm cho kết nối + khung hạn ngạch này đã tồn tại", + "cancel": "Hủy", + "createPool": "Tạo nhóm", + "editTitle": "Chỉnh sửa phân bổ", + "noKeysAdded": "Chưa có khóa API nào được phân bổ. Hãy thêm một khóa API bên dưới.", + "totalLabel": "Tổng cộng: {percent}%", + "totalExceeded": "⚠ vượt quá 100%", + "addKey": "+ Thêm khóa API…", + "equalSplit": "Chia đều", + "save": "Lưu phân bổ", + "betaPreviewLabel": "Beta — Bản xem trước giao diện.", "betaConfigSavedPrefix": "Cấu hình được lưu trong", - "betaConfigSavedSuffix": "(chưa tồn tại trên máy chủ). Việc thực thi giới hạn theo yêu cầu vẫn chưa được đưa vào quy trình proxy. Màn hình này cho phép bạn thiết kế và trực quan hóa việc phân chia hạn ngạch; Việc thực thi thực sự sẽ diễn ra trong một lần lặp lại trong tương lai với khả năng duy trì DB và chặn cuộc gọi ngược dòng.", + "betaConfigSavedSuffix": "(chưa được lưu lâu dài trên máy chủ). Việc thực thi giới hạn cho từng yêu cầu chưa được tích hợp vào quy trình xử lý của proxy. Màn hình này cho phép bạn thiết kế và trực quan hóa việc phân chia hạn ngạch; việc áp dụng thực tế sẽ được triển khai trong phiên bản tương lai với tính năng lưu trữ DB và chặn các lệnh gọi upstream.", "policyLabel": "Chính sách:", - "resetIn": "đặt lại trong", - "quotaTotal": "tổng cộng" + "resetIn": "đặt lại sau", + "quotaTotal": "tổng cộng", + "kpiAvgUtilization": "Avg utilization", + "kpiBorrowingNow": "Borrowing now", + "conceptTitle": "How Quota Share works", + "conceptIntro": "Quota Share divides a provider's quota among multiple API keys using work-conserving fair-share: each key receives a proportional slice but can borrow from the free balance without exceeding the global cap.", + "conceptFairShare": "Fair-share: each key receives quota proportional to its configured weight", + "conceptBorrowing": "Borrowing: keys can consume free balance from others without breaching the cap", + "conceptGlobalCap": "Hard global cap: the provider's absolute limit is never exceeded", + "conceptWindows": "Windows: 5h, hourly, daily, weekly, monthly — each tracked independently", + "conceptKeyHowTitle": "Enabling a key for quota", + "conceptKeyHowDesc": "Create the key normally in API Keys — it appears in the wizard's key step automatically. Tick Exclusive there to make it quota-only. No separate enable step.", + "conceptExclusiveTitle": "What \"Exclusive\" does", + "conceptExclusiveDesc": "An exclusive key only sees/uses the pool's quotaShared-* models — every other model is hidden from its /v1/models and blocked.", + "burnRateTitle": "Burn rate", + "burnRateExhaustsIn": "Exhausts in", + "dimensionResetIn": "Resets in", + "realConsumedColumn": "Consumed", + "deficitColumn": "Deficit", + "borrowingIndicator": "borrowing", + "migratedFromLocalStorageNotice": "Pools successfully migrated from localStorage.", + "policyCapAbsoluteLabel": "Absolute cap", + "policyCapAbsolutePlaceholder": "Numeric limit (optional)", + "multiDimensionLabel": "Multi-dimension", + "stackedBarTitle": "Slices by API key", + "usedSuffix": "used {percent}%", + "wizardTitle": "New quota pool", + "editPoolTitle": "Edit pool", + "saveChanges": "Save changes", + "wizardStep1Label": "Account", + "wizardStep2Label": "Limit", + "wizardStep3Label": "Keys", + "wizardStep1Title": "Choose provider connection", + "wizardStep1Subtitle": "Select the provider account this pool will share quota for, set a name and default policy.", + "wizardStep2Title": "Configure quota dimensions", + "wizardStep2Subtitle": "Define the quota plan dimensions (unit, window, limit) for the chosen connection. Leave unchanged to keep current settings.", + "wizardStep3Title": "Allocate API keys", + "wizardStep3Subtitle": "Assign API keys to this pool with weight % allocations and optional caps.", + "wizardPoolNameLabel": "Pool name", + "wizardPoolNamePlaceholder": "My quota pool", + "wizardNext": "Next", + "wizardBack": "Back", + "wizardCreatePool": "Create pool", + "wizardDimensionsEditedNotice": "Dimensions edited — will be saved as a manual override when the pool is created.", + "wizardExclusiveLabel": "Exclusive quota", + "wizardExclusiveHint": "When enabled, these API keys will only be allowed to use this pool's virtual models (allowedQuotas reconciliation is applied on save).", + "wizardPreviewLabel": "Virtual model names preview", + "wizardConnectionsLabel": "Provider connections", + "wizardPrimaryBadge": "primary", + "wizardAdditionalConnectionsNote": "Additional connections use their catalog default limits (editable later).", + "wizardSingleProviderNote": "A pool uses a single provider", + "wizardPreviewMoreModels": "+{count} more", + "accountQuotaTitle": "Account quota", + "accountQuotaNone": "—", + "logTitle": "Usage log", + "logEmpty": "No usage yet", + "groupLabel": "Group", + "newGroup": "New group", + "renameGroup": "Rename group", + "groupSelectHint": "Filter pools by group", + "groupAllocationNote": "Allocations apply to all pools in this group via the shared quota layer.", + "groupNamePrompt": "Enter group name", + "wizardGroupLabel": "Group", + "allGroups": "All groups", + "endpointsTitle": "Available endpoints", + "endpointsHint": "Call these virtual models with any allocated key — routing + quota are handled per group.", + "previewForKey": "Preview for key", + "previewKeyNone": "(all endpoints)", + "endpointsBaseUrl": "Base URL", + "endpointsCollapse": "Collapse", + "endpointsExpand": "Expand", + "endpointsAnthropicNote": "Anthropic-native", + "endpointsResponsesNote": "OpenAI Responses — codex/github", + "endpointsWsNote": "WebSocket — codex only", + "betaText": "Quota Share is functional but bugs are expected. Found one? Please report it.", + "betaReportLink": "Report an issue", + "deleteGroup": "Delete group", + "deleteGroupConfirm": "Delete this group? Its pools must be reassigned or removed first.", + "deleteGroupHasPools": "This group still has pools — reassign or delete them first.", + "ungroupedTitle": "Ungrouped", + "ungroupedHint": "These pools are not assigned to a known group. Edit a pool to move it into a real group." }, "plugins": { - "title": "Plugins", - "description": "Install and manage plugins for extending OmniRoute functionality", - "loading": "Loading plugins...", - "scanning": "Scanning...", - "scanForPlugins": "Scan for Plugins", - "noPlugins": "No plugins installed", - "noPluginsDescription": "Place plugin directories in ~/.omniroute/plugins/ and click Scan.", - "activate": "Activate", - "deactivate": "Deactivate", - "uninstall": "Uninstall", - "uninstallConfirm": "Uninstall plugin \"{name}\"?", - "pluginScanComplete": "Plugin scan complete", - "pluginScanFailed": "Plugin scan failed", - "activated": "{name} activated", - "deactivated": "{name} deactivated", - "activateFailed": "Failed to activate {name}", - "deactivateFailed": "Failed to deactivate {name}", - "uninstalled": "{name} uninstalled", - "uninstallFailed": "Failed to uninstall {name}", - "configure": "Configure: {name}", - "configurePlugin": "Configure", - "noConfigSettings": "This plugin has no configurable settings.", - "saving": "Saving...", - "saveConfiguration": "Save Configuration", - "configurationSaved": "Configuration saved", - "saveConfigurationFailed": "Failed to save configuration", - "pluginNotFound": "Plugin not found", - "version": "Version", - "author": "Author", - "description_label": "Description", - "status": "Status", - "enabled": "Enabled", - "disabled": "Disabled", - "hooks": "Hooks" + "title": "Plugin", + "description": "Cài đặt và quản lý các plugin để mở rộng chức năng của OmniRoute", + "loading": "Đang tải các plugin...", + "scanning": "Đang quét...", + "scanForPlugins": "Quét tìm plugin", + "noPlugins": "Chưa cài đặt plugin nào", + "noPluginsDescription": "Đặt các thư mục plugin vào ~/.omniroute/plugins/ và nhấp vào Quét.", + "activate": "Kích hoạt", + "deactivate": "Hủy kích hoạt", + "uninstall": "Gỡ cài đặt", + "uninstallConfirm": "Gỡ cài đặt plugin \"{name}\"?", + "pluginScanComplete": "Đã hoàn tất quét plugin", + "pluginScanFailed": "Quét plugin thất bại", + "activated": "Đã kích hoạt {name}", + "deactivated": "Đã hủy kích hoạt {name}", + "activateFailed": "Không thể kích hoạt {name}", + "deactivateFailed": "Không thể hủy kích hoạt {name}", + "uninstalled": "Đã gỡ cài đặt {name}", + "uninstallFailed": "Không thể gỡ cài đặt {name}", + "configure": "Cấu hình: {name}", + "configurePlugin": "Cấu hình", + "noConfigSettings": "Plugin này không có cài đặt nào có thể cấu hình.", + "saving": "Đang lưu...", + "saveConfiguration": "Lưu cấu hình", + "configurationSaved": "Đã lưu cấu hình", + "saveConfigurationFailed": "Không thể lưu cấu hình", + "pluginNotFound": "Không tìm thấy plugin", + "version": "Phiên bản", + "author": "Tác giả", + "description_label": "Mô tả", + "status": "Trạng thái", + "enabled": "Đã bật", + "disabled": "Đã tắt", + "hooks": "Hooks", + "installedTab": "Installed", + "marketplaceTab": "Marketplace", + "marketplaceUrlLabel": "Custom Marketplace URL", + "marketplaceUrlPlaceholder": "Leave empty for official Omniroute registry", + "saveMarketplaceUrl": "Save & Reload", + "marketplaceUrlSaved": "Marketplace URL updated", + "marketplaceEmpty": "No plugins found in marketplace.", + "marketplaceInstallComingSoon": "Marketplace installs are coming soon.", + "verified": "Verified", + "install": "Install", + "installedFromMarketplace": "Plugin {name} installed!" }, "reasoningRouting": { "title": "Reasoning routing policies", @@ -7725,12 +8818,631 @@ } }, "freeProviderRankingsPage": { - "typeAll": "__MISSING__:All Types", - "typeNoauth": "__MISSING__:No Signup", - "typeOauth": "__MISSING__:OAuth Login", - "typeApikey": "__MISSING__:API Key", - "sortTypeFirst": "__MISSING__:Easiest first", - "sortTypeFirstHelp": "__MISSING__:Group by signup effort (No Signup → OAuth Login → API Key), keeping quality order within each group", - "typeLegend": "__MISSING__:No Signup = zero setup · OAuth Login = sign in with your own account · API Key = bring your own key or that provider's free tier" + "typeAll": "Tất cả loại", + "typeNoauth": "Không cần đăng ký", + "typeOauth": "Đăng nhập OAuth", + "typeApikey": "Khóa API", + "sortTypeFirst": "Dễ thiết lập trước", + "sortTypeFirstHelp": "Nhóm theo mức độ thiết lập (Không cần đăng ký → Đăng nhập OAuth → Khóa API), đồng thời giữ thứ tự chất lượng trong từng nhóm", + "typeLegend": "Không cần đăng ký = không cần thiết lập · Đăng nhập OAuth = đăng nhập bằng tài khoản của bạn · Khóa API = dùng khóa riêng hoặc gói miễn phí của nhà cung cấp", + "title": "Free Provider Rankings", + "subtitle": "Best free providers ranked by model ELO scores from Arena AI leaderboards", + "loading": "Loading rankings...", + "errorLoading": "Failed to load rankings", + "emptyState": "No rankings available yet. Arena ELO data syncs on startup (daily) — check back shortly, or trigger a manual sync. Disable Arena ELO Sync in Feature Flags or set ARENA_ELO_SYNC_ENABLED=false to opt out.", + "bestModel": "Best", + "allCategories": "All Categories", + "categoryDefault": "Default", + "categoryCoding": "Coding", + "categoryReview": "Review", + "categoryDocumentation": "Documentation", + "categoryDebugging": "Debugging", + "colRank": "Rank", + "colProvider": "Provider", + "colTopModel": "Top Model", + "colScore": "Score", + "colAvgScore": "Avg Score", + "colModels": "Models", + "colType": "Type", + "filterConfiguredOnly": "Configured only", + "filterAvailableOnly": "Available only", + "filterAvailableOnlyHelp": "Hide providers whose connections are all rate-limited or out of quota.", + "configuredOnly": "Configured Only", + "configuredOnlyHint": "Show only providers with active connections", + "noConfiguredProviders": "No configured providers found. Add a provider connection first.", + "colConfigured": "Status" + }, + "disabled": "Disabled", + "featureFlagOmnirouteEmergencyFallbackDescription": "Route budget-exhausted requests to the emergency free fallback provider/model.", + "featureFlagArenaEloSyncEnabledDescription": "Enable periodic Arena AI leaderboard ELO sync for model intelligence rankings.", + "quotaPlans": { + "title": "Plans & Quotas", + "description": "Configure quota plans per provider — dimensions (%, requests, tokens, $) and time windows", + "providerLabel": "Provider / Connection", + "detectedPlanLabel": "Detected plan", + "manualPlanLabel": "Manual override", + "unconfiguredLabel": "Not configured — manual required", + "dimensionLabel": "Dimensions", + "addDimension": "Add dimension", + "removeDimension": "Remove", + "limitLabel": "Limit", + "unitOptions": { + "percent": "%", + "requests": "requests", + "tokens": "tokens", + "usd": "USD ($)" + }, + "windowOptions": { + "5h": "5 hours", + "hourly": "Hourly", + "daily": "Daily", + "weekly": "Weekly", + "monthly": "Monthly" + }, + "useCatalogButton": "Use catalog", + "saveOverrideButton": "Save override", + "revertToCatalogButton": "Revert to catalog", + "unknownProviderNotice": "Select a provider on the left to configure its quota plan.", + "catalogTitle": "Known catalog", + "catalogDescription": "Automatically detected plans for the following providers:" + }, + "activity": { + "title": "Activity", + "description": "Recent events feed", + "emptyTitle": "No activity yet", + "emptyDescription": "When you add providers, create combos, or rotate keys, events will appear here.", + "todayHeader": "Today", + "yesterdayHeader": "Yesterday", + "filterAll": "All", + "filterProviders": "Providers", + "filterCombos": "Combos", + "filterApiKeys": "API Keys", + "filterSettings": "Settings", + "filterQuota": "Quota", + "filterAuth": "Auth", + "filterSystem": "System", + "relative": { + "justNow": "just now", + "minutesAgo": "{n} min ago", + "hoursAgo": "{n} h ago", + "yesterday": "yesterday", + "daysAgo": "{n} days ago" + }, + "eventVerb": { + "providerAdded": "{actor} added provider {target}", + "providerRemoved": "{actor} removed provider {target}", + "providerTested": "{actor} tested provider {target}", + "comboCreated": "{actor} created combo {target}", + "comboUpdated": "{actor} updated combo {target}", + "comboDeleted": "{actor} removed combo {target}", + "apiKeyCreated": "{actor} created API key {target}", + "apiKeyRevoked": "{actor} revoked API key {target}", + "apiKeyRotated": "{actor} rotated API key {target}", + "budgetThreshold": "Budget threshold reached for {target}", + "settingUpdated": "{actor} updated setting {target}", + "authLogin": "{actor} signed in", + "authLogout": "{actor} signed out", + "cloudAgentSession": "Cloud agent session started for {target}", + "mcpToolRegistered": "MCP tool {target} registered", + "webhookCreated": "{actor} created webhook {target}", + "webhookDeleted": "{actor} removed webhook {target}", + "quotaPoolCreated": "{actor} created quota pool {target}", + "quotaPoolUpdated": "{actor} updated quota pool {target}", + "quotaPoolDeleted": "{actor} removed quota pool {target}", + "quotaPlanUpdated": "{actor} updated quota plan {target}", + "quotaStoreDriverChanged": "QuotaStore driver changed", + "updateApplied": "Update {target} applied", + "deployCompleted": "Deploy completed", + "skillInstalled": "{actor} installed skill {target}", + "skillRemoved": "{actor} removed skill {target}", + "providerCredentialsCreated": "{actor} created credentials for {target}", + "providerCredentialsApplied": "Credentials for {target} applied", + "providerCredentialsUpdated": "{actor} updated credentials for {target}", + "providerCredentialsRevoked": "{actor} revoked credentials for {target}", + "providerCredentialsBatchRevoked": "{actor} batch-revoked credentials", + "providerCredentialsBatchUpdated": "{actor} batch-updated credentials", + "providerCredentialsBulkCreated": "{actor} bulk-created credentials", + "providerCredentialsBulkImported": "{actor} bulk-imported credentials", + "providerCredentialsImported": "{actor} imported credentials", + "providerSsrfBlocked": "SSRF attempt blocked for {target}", + "authLoginSuccess": "{actor} signed in", + "authLoginError": "Login error for {actor}", + "authLoginFailed": "Login failed for {actor}", + "authLoginLocked": "{actor} locked out after too many attempts", + "authLoginMisconfigured": "Auth configuration invalid", + "authLoginSetupRequired": "Auth setup required", + "authLogoutSuccess": "{actor} signed out", + "syncTokenCreated": "{actor} created sync token", + "syncTokenRevoked": "{actor} revoked sync token", + "settingsUpdate": "{actor} updated settings", + "settingsUpdateFailed": "Settings update failed", + "serviceRevealApiKey": "{actor} revealed API key for {target}", + "genericEvent": "{actor} {target}" + } + }, + "agentBridge": { + "title": "AgentBridge", + "subtitle": "Use IDE agents with OmniRoute models — no config required", + "riskBannerTitle": "Use at your own risk", + "riskBannerBody": "AgentBridge intercepts HTTPS traffic from IDE agents. By activating it you accept responsibility for compliance with the terms of service of each agent. Never use on devices or networks where TLS inspection is prohibited.", + "riskBannerDismiss": "Dismiss", + "serverCardTitle": "AgentBridge Server", + "statusRunning": "Running", + "statusStopped": "Stopped", + "statusActive": "Active", + "statusDnsOff": "DNS off", + "statusSetupRequired": "Setup required", + "statusInvestigating": "Investigating", + "serverPort": "Port", + "serverConns": "Connections", + "serverIntercepted": "Intercepted", + "serverLastStarted": "Last started", + "startServer": "Start", + "stopServer": "Stop", + "restartServer": "Restart", + "trustCert": "Trust Cert", + "downloadCert": "Download Cert", + "certManualTitle": "Certificate couldn't be installed automatically (e.g. inside a container). The bridge can still run — trust the CA manually:", + "regenerateCert": "Regenerate Cert", + "starting": "Starting…", + "stopping": "Stopping…", + "restarting": "Restarting…", + "trusting": "Trusting…", + "regenerating": "Regenerating…", + "upstreamCaLabel": "Upstream CA Certificate (corporate)", + "upstreamCaPlaceholder": "/etc/ssl/certs/corp-ca.pem", + "upstreamCaTest": "Test TLS", + "upstreamCaTestOk": "TLS test passed", + "upstreamCaTestError": "TLS test failed — check the path and CA file", + "bypassSectionTitle": "Bypass List", + "bypassSectionDesc": "Hosts matching these patterns are tunneled directly (no TLS decryption). Defaults include banks.gov, and corporate SSO.", + "bypassDefaultsLabel": "Default bypass patterns (read-only)", + "bypassUserLabel": "Custom bypass patterns (one per line, glob or regex)", + "saveBypassList": "Save bypass list", + "agentListTitle": "IDE Agents", + "filterAll": "All", + "filterActive": "Active", + "filterSetupRequired": "Setup required", + "filterInvestigating": "Investigating", + "searchAgents": "Search agents…", + "noAgentsMatch": "No agents match the current filter", + "agentHosts": "Intercepted hosts", + "certTrusted": "Certificate trusted", + "certNotTrusted": "Certificate not trusted", + "investigatingNotice": "This agent is under investigation. Hosts and API surface are still being confirmed. Setup will be available once the upstream API is documented.", + "modelMappingsLabel": "Model mappings", + "sourceModel": "Source model (agent native)", + "targetModel": "Target model (OmniRoute)", + "noMappings": "No model mappings configured. Run setup wizard to auto-detect models.", + "selectModel": "Select…", + "saveMappings": "Save mappings", + "setupWizard": "Setup wizard", + "startDns": "Start DNS", + "stopDns": "Stop DNS", + "toggling": "Toggling…", + "viewTraffic": "View traffic", + "emptyNoProvidersTitle": "No providers configured yet", + "emptyNoProvidersBody": "To use AgentBridge, first connect at least one provider. It will be the destination where IDE requests are routed.", + "emptyGoToProviders": "Go to Providers", + "wizardTitle": "Setup wizard", + "wizardSubtitle": "3-step setup", + "wizardStep1Label": "Verify", + "wizardStep2Label": "DNS", + "wizardStep3Label": "Mappings", + "wizardStep1Desc": "Confirm the server is running and the certificate is installed.", + "wizardStep2Desc": "The following entries will be added to /etc/hosts to redirect traffic through AgentBridge:", + "wizardStep3Desc": "You can now configure model mappings in the agent card. Restart the IDE to apply changes.", + "wizardStep3Success": "Agent is configured!", + "wizardServerCheck": "AgentBridge server", + "wizardRunning": "running", + "wizardNotRunning": "not running", + "wizardCertCheck": "Certificate", + "wizardTrusted": "trusted", + "wizardNotTrusted": "not yet trusted — use Trust Cert button", + "wizardTutorialTitle": "Setup instructions:", + "wizardEnableDns": "Add /etc/hosts entries", + "wizardDnsAlreadyEnabled": "DNS already enabled for this agent", + "enablingDns": "Enabling…", + "modelSelectorTitle": "Select target model", + "modelSelectorSearch": "Search models…", + "noModelsFound": "No models found", + "quickLinks": "Quick links", + "quickLinkProviders": "Configure providers", + "quickLinkInspector": "View traffic in Traffic Inspector", + "maintenanceTitle": "Maintenance & Diagnostics", + "maintenanceSubtitle": "Self-test the capture pipeline, undo leftover system state, and move your setup between machines.", + "orphanedStateWarning": "A previous session left system state behind (DNS spoof, CA, or system proxy). Run Repair to clean it up.", + "diagnose": "Diagnose", + "diagnosing": "Diagnosing…", + "diagnoseHealthy": "Capture pipeline is healthy.", + "diagnoseUnhealthy": "Capture pipeline has problems:", + "repair": "Repair", + "repairing": "Repairing…", + "repairDone": "Repaired: {items}", + "repairNothing": "Nothing to repair — system state is clean.", + "removeCa": "Remove CA", + "removeCaConfirm": "Remove CA?", + "removeCaDone": "MITM root CA removed from the OS trust store.", + "removing": "Removing…", + "confirm": "Confirm", + "exportConfig": "Export config", + "exporting": "Exporting…", + "importConfig": "Import config", + "importing": "Importing…", + "importInvalidJson": "The selected file is not valid JSON.", + "importDone": "Imported {bypass} bypass · {hosts} hosts · {agents} agents", + "save": "Save", + "saving": "Saving…", + "cancel": "Cancel", + "back": "Back", + "next": "Next", + "done": "Done", + "loading": "Loading…", + "riskNoticeTitle": "Risk acknowledgment", + "riskNoticeBody": "AgentBridge will intercept HTTPS traffic from this agent by redirecting its API hosts via DNS. Only enable if you accept responsibility for compliance with the agent's terms of service and any applicable network policies.", + "pageMoved": { + "goNow": "Go now", + "message": "The MITM Proxy now lives under AgentBridge.", + "title": "This page has moved" + } + }, + "trafficInspector": { + "title": "Traffic Inspector", + "subtitle": "Monitor LLM calls and debug any application's HTTPS traffic", + "captureModesTitle": "Capture Modes", + "agentBridgeMode": "AgentBridge", + "agentBridgeModeDesc": "Capture traffic from all connected IDE agents", + "customHostsMode": "Custom Hosts", + "customHostsModeDesc": "Add specific hosts to intercept", + "httpProxyMode": "HTTP Proxy", + "httpProxyModeDesc": "Use HTTP_PROXY environment variable", + "systemWideMode": "System-wide", + "systemWideModeDesc": "Intercept all system traffic (advanced)", + "tproxyMode": "TPROXY Decrypt", + "tproxyModeUnavailable": "TPROXY decrypt requires Linux + root + the native addon", + "filterBarTitle": "Filters", + "profileLlmOnly": "LLM only", + "profileCustom": "Custom", + "profileAll": "All", + "filterHost": "Filter host…", + "filterAgent": "Agent", + "filterStatus": "Status", + "pauseBtn": "Pause", + "resumeBtn": "Resume", + "clearBtn": "Clear", + "exportHar": "Export .har", + "recordSession": "REC", + "stopSession": "Stop", + "liveBadge": "live", + "offlineBadge": "offline", + "noRequests": "No requests captured yet.", + "noRequestsDesc": "Make sure AgentBridge is running or enable another capture mode.", + "selectRequest": "Select a request to inspect it.", + "tabConversation": "Conversation", + "tabHeaders": "Headers", + "tabRequest": "Request", + "tabResponse": "Response", + "tabTiming": "Timing", + "tabLlm": "LLM", + "tabStats": "Stats", + "requestHeaders": "Request Headers", + "responseHeaders": "Response Headers", + "rawEvents": "Raw events", + "mergedView": "Merged view", + "noBody": "No body.", + "streaming": "streaming…", + "manageHosts": "Manage hosts", + "copySnippet": "Copy proxy snippet", + "addHost": "Add", + "hostPlaceholder": "api.openai.com", + "noHostsYet": "No custom hosts added yet.", + "noSessionsYet": "No sessions yet", + "allTraffic": "All traffic (no session)", + "sessionsDropdown": "Sessions", + "annotationPlaceholder": "Add a note…", + "contextFingerprint": "Context fingerprint", + "llmProvider": "Detected provider", + "llmApiKind": "API kind", + "llmModel": "Model", + "llmMessages": "Messages", + "llmStream": "Stream", + "llmMappedTo": "Mapped to", + "llmCostEstimate": "Cost estimate", + "systemProxyExitWarning": "System-wide proxy still active — leave page anyway?", + "customHostsTitle": "Custom Hosts", + "loading": "Loading…", + "copied": "Copied!", + "copy": "Copy", + "httpProxyTitle": "HTTP Proxy Snippet — port {port}", + "notRecording": "Not recording", + "anyStatus": "Any status", + "liveOnly": "Live", + "viewingRecordedSession": "Viewing recorded session", + "backToLive": "Back to live", + "untitledSession": "Untitled session", + "contextHistory": "Context History", + "modelResponse": "Model Response", + "conversationNoMessages": "No messages found in this request.", + "conversationNotAvailable": "Conversation data not available. This may not be an LLM request or the body could not be parsed.", + "loadingCharts": "Loading charts…", + "statsErrors": "Errors", + "statsLatency": "Latency (last 50 requests)", + "statsNoData": "No requests yet. Start a session recording to capture data for stats.", + "statsStatusDistribution": "Status distribution", + "statsSuccessful": "Successful", + "statsTotalRequests": "Total requests", + "timingProxyOverhead": "Proxy overhead", + "timingUpstreamResponse": "Upstream response", + "timingNoData": "No timing data available.", + "timingTotalLatency": "Total latency", + "timingTimestamp": "Timestamp", + "timingMethod": "Method", + "timingStatus": "Status", + "timingRequestSize": "Request size", + "timingResponseSize": "Response size", + "pausedNewBadge": "{count} new", + "clearContextFilter": "clear" + }, + "cliCommon": { + "concept": { + "code": { + "title": "CLI Code", + "phrase": "Code tools you point at OmniRoute", + "flow": "You → CLI Code → OmniRoute → Provider", + "seeOther": "See →" + }, + "agent": { + "title": "CLI Agents", + "phrase": "Broad-purpose autonomous CLI agents you point at OmniRoute", + "flow": "You → CLI Agent → OmniRoute → Provider", + "seeOther": "See →" + }, + "acp": { + "title": "ACP Agents", + "phrase": "CLIs that OmniRoute spawns as execution backend (reverse flow)", + "flow": "Client → OmniRoute → spawn CLI (stdio/ACP) → response", + "seeOther": "See →" + } + }, + "comparison": { + "title": "Understand the 3 CLI types in OmniRoute", + "thisPage": "This page", + "open": "Open →", + "code": { + "title": "Code tool", + "desc": "Points to Omni", + "flow": "you → CLI → Omni → provider", + "examples": "e.g.: claude, codex" + }, + "agent": { + "title": "Broad autonomous agent", + "desc": "Points to Omni", + "flow": "you → agent → Omni", + "examples": "e.g.: hermes, goose" + }, + "acp": { + "title": "CLI used as backend by Omni", + "desc": "Reverse execution", + "flow": "Omni → spawn CLI → resp", + "examples": "e.g.: claude, codex (ACP)" + } + }, + "card": { + "detected": "Detected", + "notDetected": "Not detected", + "configured": "Configured", + "notConfigured": "Not configured", + "configure": "Configure →", + "howToInstall": "How to install →", + "manualConfig": "Manual config", + "installGuide": "Install guide", + "endpointLabel": "Endpoint", + "baseUrlFull": "Full Base URL", + "baseUrlPartial": "Partial Base URL", + "refreshDetection": "Refresh detection", + "alsoAcp": "also ACP", + "connectProviderHint": "Connect a provider in Providers" + }, + "detail": { + "back": "Back", + "apply": "Save", + "reset": "Clear", + "manualConfig": "Manual configuration", + "vendor": "Vendor", + "category": "Type", + "detectionStatus": "Detection", + "configStatus": "Configuration", + "baseUrlLabel": "Base URL", + "apiKeyLabel": "API Key", + "modelMappingLabel": "Model mapping", + "noActiveProviders": "No active providers.", + "noActiveProvidersDesc": "Go to Providers to connect at least 1 provider before configuring the CLI.", + "openProviders": "Open Providers →" + } + }, + "cliCode": { + "pageTitle": "CLI Code's", + "pageSubtitle": "Code tools pointing to OmniRoute", + "searchPlaceholder": "Search CLI…", + "filterDetectionLabel": "Detection", + "filterBaseUrlLabel": "Base URL", + "detectionAll": "All", + "detectionInstalled": "Installed", + "detectionNotFound": "Not found", + "baseUrlAll": "All", + "baseUrlFull": "Full", + "baseUrlPartial": "Partial" + }, + "cliAgents": { + "pageTitle": "CLI Agents", + "pageSubtitle": "Broad-purpose autonomous CLI agents", + "refreshDetection": "Refresh detection", + "searchPlaceholder": "Search agent…", + "detectionFilterLabel": "Detection", + "detectionAll": "All", + "detectionInstalled": "Installed", + "detectionNotInstalled": "Not installed", + "visibleCount": "{count} visible", + "emptyState": "No CLI agents found with the current filters." + }, + "acpAgents": { + "pageTitle": "ACP Agents", + "pageSubtitle": "CLIs that OmniRoute spawns as execution backend", + "scanning": "Detecting agents…", + "refresh": "Refresh", + "setupGuideTitle": "Setup guide", + "setupGuideDetectCliTitle": "Detect CLI", + "setupGuideDetectCliDesc": "Agents are identified by running the --version command in PATH.", + "setupGuideCustomAgentTitle": "Add custom agent", + "setupGuideCustomAgentDesc": "Fill in the form below to register a custom CLI agent.", + "setupGuideCommandMissingTitle": "Command not found", + "setupGuideCommandMissingDesc": "Check that the binary is in PATH.", + "fingerprintSettingsHint": "Configure routing and fingerprints in", + "settingsRoutingLink": "Settings → Routing", + "installed": "Installed", + "notFound": "Not found", + "builtIn": "Built-in", + "custom": "Custom", + "agentUseCaseHint": "Available for spawn via ACP.", + "remove": "Remove", + "addCustomAgent": "Add custom agent", + "addCustomAgentDesc": "Register a custom CLI agent to be spawned via ACP.", + "addAgent": "Add agent", + "agentName": "Name", + "agentNamePlaceholder": "e.g.: My Agent", + "binaryName": "Binary", + "binaryNamePlaceholder": "e.g.: myagent", + "versionCommand": "Version command", + "versionCommandPlaceholder": "e.g.: myagent --version", + "spawnArgs": "Spawn arguments", + "spawnArgsPlaceholder": "e.g.: --quiet, --json", + "cliCodeRedirectCta": "Open CLI Code" + }, + "agentSkills": { + "pageTitle": "Agent Skills", + "pageSubtitle": "Teach your agent to operate OmniRoute — 22 API areas + 20 CLI families", + "conceptCard": { + "agent": { + "title": "Agent Skills — Outbound", + "description": "Agent Skills are machine-readable SKILL.md documents that external AI agents (Claude Code, Cursor, Copilot…) fetch from GitHub to learn how to operate OmniRoute via REST or CLI. They are read by the agent, not executed by OmniRoute.", + "crossLinkLabel": "Understand the difference →" + }, + "omni": { + "title": "Omni Skills — Inbound", + "description": "Omni Skills are sandbox tools that OmniRoute injects into the model's context on every request. They are executed by OmniRoute, not read by the agent.", + "crossLinkLabel": "Understand the difference →" + }, + "comparison": { + "colAgent": "Agent Skills", + "colOmni": "Omni Skills", + "whatIs": { + "label": "What it is", + "agent": "Machine-readable SKILL.md that teaches an external agent to operate OmniRoute", + "omni": "Executable tools that OmniRoute injects as tools into LLM requests" + }, + "direction": { + "label": "Direction", + "agent": "Outbound — external agent learns to control OmniRoute", + "omni": "Inbound — OmniRoute gives tools to models passing through it" + }, + "executor": { + "label": "Executor", + "agent": "External agent (reads markdown → acts via API/CLI)", + "omni": "OmniRoute itself (intercepts tool_calls, Docker sandbox)" + }, + "storage": { + "label": "Storage", + "agent": "Dynamic catalog (/api/agent-skills) → SKILL.md on GitHub", + "omni": "SQLite (SkillsMP / skills.sh / local)" + }, + "tagline": { + "label": "Tagline", + "agent": "Teach your agent to use OmniRoute", + "omni": "Give executable tools to OmniRoute models" + } + } + }, + "filters": { + "category": "Category", + "area": "Area", + "searchPlaceholder": "Search skills…" + }, + "categoryApi": "API", + "categoryCli": "CLI", + "categoryConfig": "Config", + "filterAll": "All", + "coverageLabel": "Coverage", + "mcpUrl": "MCP URL", + "a2aLink": "A2A", + "copyUrl": "Copy URL", + "viewOnGithub": "View on GitHub", + "previewLoading": "Loading skill documentation…", + "previewError": "Failed to load skill documentation.", + "previewEmpty": "Select a skill to preview its documentation.", + "generateButton": "Generate missing skills", + "coverageBar": { + "complete": "Complete", + "partial": "Partial" + }, + "noSkillsFound": "No skills found matching your filters.", + "regenerateConfirm": "This will regenerate all missing SKILL.md files. Continue?", + "regenerateRunning": "Regenerating skills…", + "regenerateSuccess": "Skills regenerated successfully.", + "regenerateError": "Failed to regenerate skills." + }, + "discovery": { + "title": "Provider Discovery", + "subtitle": "Scan providers for free/unlimited access methods and review findings. Opt-in, local-only.", + "scanLabel": "Provider to scan", + "scanPlaceholder": "e.g. huggingchat", + "scan": "Scan", + "scanning": "Scanning…", + "scanQueued": "Scan complete for {provider}.", + "scanFailed": "Scan failed.", + "loadFailed": "Failed to load discovery results.", + "localOnlyNote": "This tool is local-only (loopback). Scans run from this machine and are never reachable remotely.", + "verify": "Verify", + "verifyFailed": "Failed to verify finding.", + "delete": "Delete", + "deleteFailed": "Failed to delete finding.", + "deleteTitle": "Delete discovery result", + "deleteConfirm": "Delete the discovery finding for {provider}? This cannot be undone.", + "emptyTitle": "No discovery results yet", + "emptyDescription": "Run a scan above to look for free access methods on a provider.", + "risk": "Risk", + "method": "Method", + "auth": "Auth", + "feasibility": "Feasibility", + "models": "Models" + }, + "chaosConfig": { + "pageTitle": "Chaos Mode", + "pageSubtitle": "Run multiple AI models in parallel or collaboratively on the same task", + "enableChaos": "Enable Chaos Mode", + "enableChaosDesc": "Allow API keys with chaos mode enabled to use this feature", + "mode": "Default Mode", + "modeParallel": "Parallel", + "modeCollaborative": "Collaborative", + "modeParallelDesc": "All models run simultaneously — fastest results", + "modeCollaborativeDesc": "Models chain outputs — each sees the previous result", + "timeout": "Timeout (ms)", + "timeoutDesc": "Max time per model call (5000-600000ms)", + "systemPrompt": "System Prompt (optional)", + "systemPromptDesc": "Custom instructions for all chaos mode model instances", + "providerOverrides": "Provider Overrides", + "providerOverridesDesc": "Select specific models per provider for chaos mode", + "providerId": "Provider", + "modelId": "Model", + "addProvider": "Add Provider", + "removeProvider": "Remove", + "saveConfig": "Save Configuration", + "configSaved": "Chaos configuration saved successfully", + "configError": "Failed to save chaos configuration", + "configReset": "Reset to Defaults", + "keyPermission": "Chaos Mode Access", + "keyPermissionDesc": "Allow this API key to use Chaos Mode (multi-model parallel execution)", + "testButton": "Test Chaos Mode", + "testTask": "Write a short poem about artificial intelligence", + "loadingProviderModels": "Loading providers..." } } diff --git a/tests/unit/i18n-vi-completeness.test.ts b/tests/unit/i18n-vi-completeness.test.ts new file mode 100644 index 0000000000..aa938a533f --- /dev/null +++ b/tests/unit/i18n-vi-completeness.test.ts @@ -0,0 +1,83 @@ +import assert from "node:assert/strict"; +import test from "node:test"; +import { parse } from "@formatjs/icu-messageformat-parser"; + +import en from "../../src/i18n/messages/en.json" with { type: "json" }; +import vi from "../../src/i18n/messages/vi.json" with { type: "json" }; + +type MessageEntry = { + key: string; + value: string; +}; + +function flattenMessages(value: unknown, segments: Array = []): MessageEntry[] { + if (typeof value === "string") { + return [{ key: segments.map(String).join("."), value }]; + } + if (Array.isArray(value)) { + return value.flatMap((child, index) => flattenMessages(child, [...segments, index])); + } + if (value && typeof value === "object") { + return Object.entries(value).flatMap(([key, child]) => + flattenMessages(child, [...segments, key]) + ); + } + return []; +} + +function placeholderNames(value: string): string[] { + return [...value.matchAll(/\{\s*([A-Za-z][A-Za-z0-9_]*)\s*(?=[,}])/g)] + .map((match) => match[1]) + .sort(); +} + +const englishMessages = flattenMessages(en); +const vietnameseMessages = flattenMessages(vi); +const vietnameseByKey = new Map(vietnameseMessages.map((entry) => [entry.key, entry.value])); + +test("Vietnamese locale has complete key parity with English", () => { + assert.deepEqual( + vietnameseMessages.map((entry) => entry.key).sort(), + englishMessages.map((entry) => entry.key).sort() + ); +}); + +test("Vietnamese locale has no internal missing markers or empty fallbacks", () => { + const invalid = vietnameseMessages.filter( + ({ value }) => !value.trim() || /__(?:MISSING|TODO)__:?/i.test(value) + ); + assert.deepEqual(invalid, []); +}); + +test("Vietnamese locale preserves every ICU placeholder name", () => { + const mismatches = englishMessages.flatMap(({ key, value }) => { + const translated = vietnameseByKey.get(key); + if (translated === undefined) return [{ key, reason: "missing" }]; + const sourceNames = placeholderNames(value); + const targetNames = placeholderNames(translated); + return JSON.stringify(sourceNames) === JSON.stringify(targetNames) + ? [] + : [{ key, sourceNames, targetNames }]; + }); + assert.deepEqual(mismatches, []); +}); + +test("Vietnamese locale introduces no ICU parse regression", () => { + const regressions = englishMessages.flatMap(({ key, value }) => { + try { + parse(value, { captureLocation: false, shouldParseSkeletons: true }); + } catch { + return []; + } + + const translated = vietnameseByKey.get(key); + if (translated === undefined) return [{ key, reason: "missing" }]; + try { + parse(translated, { captureLocation: false, shouldParseSkeletons: true }); + return []; + } catch (error) { + return [{ key, reason: error instanceof Error ? error.message : String(error) }]; + } + }); + assert.deepEqual(regressions, []); +});