From ee931988aa6548f23e2c61f18ebc7affd1e6daee Mon Sep 17 00:00:00 2001 From: Vucius Date: Fri, 12 Jun 2026 20:39:41 +0900 Subject: [PATCH 1/8] fix_shot --- src-tauri/src/commands/mod.rs | 2 +- src-tauri/src/commands/proxy.rs | 8 +- src-tauri/src/lib.rs | 2 +- src-tauri/src/modules/account.rs | 6 +- src-tauri/src/modules/tray.rs | 3 +- src/locales/ar.json | 4 +- src/locales/en.json | 48 +- src/locales/es.json | 4 +- src/locales/ja.json | 4 +- src/locales/ko.json | 4 +- src/locales/my.json | 4 +- src/locales/pt.json | 4 +- src/locales/ru.json | 4 +- src/locales/tr.json | 4 +- src/locales/vi.json | 4 +- src/locales/zh-TW.json | 4 +- src/locales/zh.json | 2208 +++++++++++++++--------------- src/stores/useAccountStore.ts | 17 +- 18 files changed, 1175 insertions(+), 1159 deletions(-) diff --git a/src-tauri/src/commands/mod.rs b/src-tauri/src/commands/mod.rs index 5301d1b0d..9b7393707 100644 --- a/src-tauri/src/commands/mod.rs +++ b/src-tauri/src/commands/mod.rs @@ -632,7 +632,7 @@ fn is_sensitive_path(path: &Path) -> bool { .any(|prefix| lower == *prefix || lower.starts_with(prefix)) } -fn validate_user_json_path(path: &str, must_exist: bool) -> Result { +pub(crate) fn validate_user_json_path(path: &str, must_exist: bool) -> Result { let requested = PathBuf::from(path); if requested.as_os_str().is_empty() { return Err("invalid_path: empty path".to_string()); diff --git a/src-tauri/src/commands/proxy.rs b/src-tauri/src/commands/proxy.rs index 5e365cdb5..fa1d3e2ee 100644 --- a/src-tauri/src/commands/proxy.rs +++ b/src-tauri/src/commands/proxy.rs @@ -412,13 +412,15 @@ pub async fn get_proxy_logs_count() -> Result { /// 导出所有日志到指定文件 #[tauri::command] pub async fn export_proxy_logs(file_path: String) -> Result { + let validated_path = super::validate_user_json_path(&file_path, false)?; + let logs = crate::modules::proxy_db::get_all_logs_for_export()?; let count = logs.len(); let json = serde_json::to_string_pretty(&logs) .map_err(|e| format!("Failed to serialize logs: {}", e))?; - std::fs::write(&file_path, json).map_err(|e| format!("Failed to write file: {}", e))?; + std::fs::write(&validated_path, json).map_err(|e| format!("Failed to write file: {}", e))?; Ok(count) } @@ -426,6 +428,8 @@ pub async fn export_proxy_logs(file_path: String) -> Result { /// 导出指定的日志JSON到文件 #[tauri::command] pub async fn export_proxy_logs_json(file_path: String, json_data: String) -> Result { + let validated_path = super::validate_user_json_path(&file_path, false)?; + // Parse to count items let logs: Vec = serde_json::from_str(&json_data).map_err(|e| format!("Failed to parse JSON: {}", e))?; @@ -435,7 +439,7 @@ pub async fn export_proxy_logs_json(file_path: String, json_data: String) -> Res let pretty_json = serde_json::to_string_pretty(&logs).map_err(|e| format!("Failed to serialize: {}", e))?; - std::fs::write(&file_path, pretty_json).map_err(|e| format!("Failed to write file: {}", e))?; + std::fs::write(&validated_path, pretty_json).map_err(|e| format!("Failed to write file: {}", e))?; Ok(count) } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 9ccd15d3e..3601d5003 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -261,7 +261,7 @@ pub fn run() { info!("🔐 Web UI Password: (Same as API Key)"); } info!("💡 Tips: You can use these keys to login to Web UI and access AI APIs."); - info!("💡 Search docker logs or grep gui_config.json to find them."); + info!("💡 View gui_config.json or check environment variables to find them."); info!("--------------------------------------------------"); // [FIX #1460] Persist environment overrides to ensure they are visible in Web UI/load_config diff --git a/src-tauri/src/modules/account.rs b/src-tauri/src/modules/account.rs index 368704d75..cdb3bfb82 100644 --- a/src-tauri/src/modules/account.rs +++ b/src-tauri/src/modules/account.rs @@ -1749,8 +1749,7 @@ pub async fn fetch_quota_with_retry(account: &mut Account) -> crate::error::AppR } // 3. Handle 401 error - if let Err(AppError::Network(_, status)) = result { - if let Some(code) = status { + if let Err(AppError::Network(_, Some(code))) = result { if code == 401 { modules::logger::log_warn(&format!( "401 Unauthorized for {}, forcing refresh...", @@ -1841,8 +1840,7 @@ pub async fn fetch_quota_with_retry(account: &mut Account) -> crate::error::AppR } } - if let Err(AppError::Network(_, status)) = retry_result { - if let Some(code) = status { + if let Err(AppError::Network(_, Some(code))) = retry_result { if code == 403 { let mut q = QuotaData::new(); q.is_forbidden = true; diff --git a/src-tauri/src/modules/tray.rs b/src-tauri/src/modules/tray.rs index 5381369ca..a27ddb9a2 100644 --- a/src-tauri/src/modules/tray.rs +++ b/src-tauri/src/modules/tray.rs @@ -15,8 +15,7 @@ pub fn create_tray(app: &tauri::AppHandle) -> tauri::Result<()> { let icon_bytes = include_bytes!("../../icons/tray-icon.png"); let img = image::load_from_memory(icon_bytes) .map_err(|e| { - tauri::Error::Io(std::io::Error::new( - std::io::ErrorKind::Other, + tauri::Error::Io(std::io::Error::other( e.to_string(), )) })? diff --git a/src/locales/ar.json b/src/locales/ar.json index 3aa95d802..5d3e050fa 100644 --- a/src/locales/ar.json +++ b/src/locales/ar.json @@ -1015,7 +1015,7 @@ "placeholder": "أدخل كلمة مرور الإدارة أو مفتاح API", "btn_login": "تحقق ودخول", "note": "ملاحظة: إذا تم تعيين كلمة مرور إدارة منفصلة، يرجى إدخالها؛ وإلا، أدخل مفتاح API.", - "lookup_hint": "إذا نسيت، قم بتشغيل docker logs antigravity-manager للعثور على مفتاح API الحالي أو كلمة مرور واجهة الويب", + "lookup_hint": "View gui_config.json or check environment variables to find them.", "config_hint": "أو قم بتشغيل grep -E '\"api_key\"|\"admin_password\"' ~/.antigravity_tools/gui_config.json للعرض." }, "token_stats": { @@ -1186,4 +1186,4 @@ "hint_max_ips": "0 = غير محدود", "hint_curfew": "اتركه فارغًا لتعطيله. بناءً على وقت الخادم." } -} \ No newline at end of file +} diff --git a/src/locales/en.json b/src/locales/en.json index 61821994d..446abcda8 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1,4 +1,4 @@ -{ +{ "common": { "loading": "Loading...", "empty": "Empty", @@ -86,7 +86,7 @@ "logout": "Logout" }, "dashboard": { - "hello": "Hello, User 👋", + "hello": "Hello, User 馃憢", "refresh_quota": "Refresh Quota", "refreshing": "Refreshing...", "total_accounts": "Total Accounts", @@ -174,15 +174,15 @@ "validation_url_copied": "Verification link copied to clipboard", "fix_guide": { "title": "Terminal Quick Fix (Resolves internal 403s)", - "step1_title": "🚀 Quickest Solution", + "step1_title": "馃殌 Quickest Solution", "step1_desc": "Open your Terminal and run the following command to tell Google \"it's me\", which resolves most 403 blocks:", "step1_li1": "Press Enter, input <1>Y when prompted to continue.", "step1_li2": "Your browser will open automatically, select your account and click \"Allow\".", "step1_li3": "Once you see <1>You are now authenticated, you're all set!", - "step2_title": "🧹 If that fails (Clear Cache)", + "step2_title": "馃Ч If that fails (Clear Cache)", "step2_li1_prefix": "Run this to clear your old credentials:", "step2_li2_prefix": "Then log in again:", - "tips_title": "💡 Common Tips", + "tips_title": "馃挕 Common Tips", "tip1": "If you still get 403, try running <1>unset GOOGLE_APPLICATION_CREDENTIALS in terminal first.", "tip2": "For production environments, using a <1>Service Account JSON key is highly recommended for stability and headless operation.", "tip3": "If it still fails, check the Generative Language API in <1>Google Cloud Console to see if permissions are frozen. If so, your account is under risk control. Please let the account cool down for 72 hours before trying again.", @@ -388,7 +388,7 @@ "monitored_models_label": "Monitored Models (Trigger Conditions)", "monitored_models_desc": "Select at least one. Protection triggers if ANY selected model falls below threshold", "range": "Range", - "example": "Example: At {{percentage}}%, an account with {{total}} quota will be disabled when remaining ≤ {{threshold}}", + "example": "Example: At {{percentage}}%, an account with {{total}} quota will be disabled when remaining 鈮?{{threshold}}", "auto_restore_info": "Account will be automatically re-enabled when quota resets" }, "pinned_quota_models": { @@ -508,7 +508,7 @@ "http_api_port_placeholder": "Default port 19527", "http_api_port_invalid": "Invalid port number (range: 1024-65535)", "http_api_settings_saved": "HTTP API settings saved, restart required to apply", - "http_api_restart_required": "⚠️ Restart required to apply" + "http_api_restart_required": "鈿狅笍 Restart required to apply" }, "debug": { "title": "Debug Console", @@ -539,7 +539,7 @@ "telegram": "Telegram Channel", "github": "GitHub", "view_code": "View Code", - "copyright": "Copyright © 2025-2026 Antigravity. All rights reserved.", + "copyright": "Copyright 漏 2025-2026 Antigravity. All rights reserved.", "check_update": "Check for Updates", "checking_update": "Checking...", "latest_version": "You're up to date", @@ -658,10 +658,10 @@ "auto_start_tooltip": "Automatically starts the local API Proxy service when the app launches.", "allow_lan_access": "Allow LAN Access", "allow_lan_access_tooltip": "When enabled, the service binds to 0.0.0.0 so other devices on your LAN can access it. Keep authorization enabled and protect your API key; restart required to apply.", - "allow_lan_access_hint_enabled": "🌐 Listening on 0.0.0.0, LAN devices can access", - "allow_lan_access_hint_disabled": "🔒 Listening on 127.0.0.1 only, localhost access (Privacy First)", - "allow_lan_access_warning": "⚠️ LAN devices can access when enabled. Keep your API key secure", - "allow_lan_access_restart_hint": "ℹ️ Service restart required to apply changes", + "allow_lan_access_hint_enabled": "馃寪 Listening on 0.0.0.0, LAN devices can access", + "allow_lan_access_hint_disabled": "馃敀 Listening on 127.0.0.1 only, localhost access (Privacy First)", + "allow_lan_access_warning": "鈿狅笍 LAN devices can access when enabled. Keep your API key secure", + "allow_lan_access_restart_hint": "鈩癸笍 Service restart required to apply changes", "api_key": "API Key", "api_key_tooltip": "Shared secret used by clients when proxy authorization is enabled. Regenerating the key immediately invalidates the old one.", "btn_regenerate": "Regenerate Key", @@ -716,11 +716,11 @@ "hint": "Available models: {{count}}. Select a suggestion or type a custom model id.", "error": "Failed to fetch models: {{error}}", "select_placeholder": "Select model...", - "opus": "Opus family → z.ai model", + "opus": "Opus family 鈫?z.ai model", "opus_tooltip": "Default z.ai model id used when the incoming model contains \"opus\" (e.g. claude-opus-*).", - "sonnet": "Sonnet family → z.ai model", + "sonnet": "Sonnet family 鈫?z.ai model", "sonnet_tooltip": "Default z.ai model id used for other Claude models (e.g. claude-sonnet-* and most claude-* requests).", - "haiku": "Haiku family → z.ai model", + "haiku": "Haiku family 鈫?z.ai model", "haiku_tooltip": "Default z.ai model id used when the incoming model contains \"haiku\" (e.g. claude-haiku-*).", "advanced_title": "Advanced overrides", "advanced_tooltip": "Optional exact-match overrides. If an incoming model string matches a rule key, it will be replaced with the mapped z.ai model id.", @@ -987,7 +987,7 @@ "apply_presets": "Apply Presets", "presets_applied": "Presets applied successfully", "preset_default": "Default Preset", - "preset_default_desc": "GPT-4 → Gemini Pro, Claude → Opus", + "preset_default_desc": "GPT-4 鈫?Gemini Pro, Claude 鈫?Opus", "preset_performance": "Performance First", "preset_performance_desc": "Use high-performance models for all", "preset_cost": "Cost Optimized", @@ -1041,12 +1041,12 @@ }, "expert_title": "Expert Custom Routing", "expert_subtitle": "Precise matching for any original model ID.", - "custom_mapping_tip": "💡 Supports manual input of any model ID to experience unreleased models (e.g. claude-opus-4-6).", + "custom_mapping_tip": "馃挕 Supports manual input of any model ID to experience unreleased models (e.g. claude-opus-4-6).", "custom_mapping_warning": "Note: Not all accounts support unreleased models.", - "money_saving_tip": "💰 Cost-saving tip:", + "money_saving_tip": "馃挵 Cost-saving tip:", "haiku_optimization_tip": "Claude CLI uses {{model}} for background tasks by default. Map it to a cheaper Flash model to save ~95% costs", "haiku_optimization_btn": "Quick Optimize", - "haiku_tip_title": "💰 Cost-saving tip:", + "haiku_tip_title": "馃挵 Cost-saving tip:", "haiku_tip_body_before": "Claude CLI defaults to", "haiku_tip_body_after": "for background tasks; mapping it to a cheaper Flash model can save about 95% of the cost.", "haiku_tip_action": "Optimize", @@ -1055,7 +1055,7 @@ "add_mapping": "Add Mapping", "current_list": "Custom List", "no_custom_mapping": "No custom mappings yet", - "gemini3_only_warning": "⚠️ Gemini 3 series only", + "gemini3_only_warning": "鈿狅笍 Gemini 3 series only", "default_suffix": " (Default)", "original_id": "Original ID", "route_to": "Route To", @@ -1073,7 +1073,7 @@ "gemini_label": "Gemini Protocol", "gemini_tools": "Google AI SDK, LangChain", "quick_integration": "Quick Integration", - "click_tip": "👆 Click a model to update code examples", + "click_tip": "馃憜 Click a model to update code examples", "copy_base": "Copy Base" }, "supported_models": { @@ -1111,7 +1111,7 @@ "sync_error": "Sync failed: {{error}}" }, "sync_confirm_title": "Sync Confirmation", - "sync_confirm_message": "Ready to sync {{name}} configuration. ⚠️ Warning: This will overwrite your existing local configuration files (e.g. login tokens, API Keys). Are you sure you want to continue?" + "sync_confirm_message": "Ready to sync {{name}} configuration. 鈿狅笍 Warning: This will overwrite your existing local configuration files (e.g. login tokens, API Keys). Are you sure you want to continue?" } }, "monitor": { @@ -1223,7 +1223,7 @@ "error_invalid_key": "Invalid password or API Key, please try again", "error_network": "Network connection failed, please check if the service is running", "note": "Note: If a separate management password is set, please enter it; otherwise, enter API_KEY.", - "lookup_hint": "If forgotten, run docker logs antigravity-manager to find Current API Key or Web UI Password", + "lookup_hint": "View gui_config.json or check environment variables to find them.", "config_hint": "Or run grep -E '\"api_key\"|\"admin_password\"' ~/.antigravity_tools/gui_config.json to view." }, "token_stats": { @@ -1391,4 +1391,4 @@ "hint_max_ips": "0 = Unlimited", "hint_curfew": "Leave empty to disable. Based on server time." } -} \ No newline at end of file +} diff --git a/src/locales/es.json b/src/locales/es.json index d7432c409..8067e40fd 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -1011,7 +1011,7 @@ "placeholder": "Ingrese contraseña de administración o Clave API", "btn_login": "Verificar y Entrar", "note": "Nota: Si se estableció una contraseña de administración separada, ingrésela; de lo contrario, ingrese la API_KEY.", - "lookup_hint": "Si olvidó, ejecute docker logs antigravity-manager para encontrar la Current API Key o Web UI Password", + "lookup_hint": "View gui_config.json or check environment variables to find them.", "config_hint": "O ejecute grep -E '\"api_key\"|\"admin_password\"' ~/.antigravity_tools/gui_config.json para ver." }, "token_stats": { @@ -1084,4 +1084,4 @@ "hint_max_ips": "0 significa ilimitado", "hint_curfew": "Dejar vacío para desactivar. Basado en la hora del servidor." } -} \ No newline at end of file +} diff --git a/src/locales/ja.json b/src/locales/ja.json index 9b2d3e312..d0395ffa8 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1166,7 +1166,7 @@ "error_invalid_key": "パスワードまたは API キーが無効です。再試行してください", "error_network": "ネットワーク接続に失敗しました。サービスが実行中か確認してください", "note": "注意:独立した管理パスワードが設定されている場合は管理パスワードを入力してください。そうでない場合は API_KEY を入力してください。", - "lookup_hint": "お忘れの場合は、docker logs antigravity-manager を実行して Current API Key または Web UI Password を探してください", + "lookup_hint": "View gui_config.json or check environment variables to find them.", "config_hint": "または grep -E '\"api_key\"|\"admin_password\"' ~/.antigravity_tools/gui_config.json を実行して確認してください。" }, "token_stats": { @@ -1334,4 +1334,4 @@ "hint_max_ips": "0 は制限なしを意味します", "hint_curfew": "空欄で無効。サーバー時間に基づきます。" } -} \ No newline at end of file +} diff --git a/src/locales/ko.json b/src/locales/ko.json index 0fa17b0f0..2c1352947 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1048,7 +1048,7 @@ "error_invalid_key": "비밀번호 또는 API 키가 잘못되었습니다. 다시 시도하십시오", "error_network": "네트워크 연결에 실패했습니다. 서비스가 실행 중인지 확인하십시오", "note": "참고: 별도의 관리 비밀번호가 설정된 경우 관리 비밀번호를 입력하십시오. 그렇지 않으면 API_KEY를 입력하십시오.", - "lookup_hint": "잊으신 경우 docker logs antigravity-manager를 실행하여 Current API Key 또는 Web UI Password를 찾으십시오.", + "lookup_hint": "View gui_config.json or check environment variables to find them.", "config_hint": "또는 grep -E '\"api_key\"|\"admin_password\"' ~/.antigravity_tools/gui_config.json을 실행하여 확인하십시오." }, "token_stats": { @@ -1216,4 +1216,4 @@ "hint_max_ips": "0 = 무제한", "hint_curfew": "비워두면 비활성화됩니다. 서버 시간 기준." } -} \ No newline at end of file +} diff --git a/src/locales/my.json b/src/locales/my.json index e8101f699..50a5e2a39 100644 --- a/src/locales/my.json +++ b/src/locales/my.json @@ -1011,7 +1011,7 @@ "placeholder": "Masukkan kata laluan pengurusan atau Kunci API", "btn_login": "Sahkan dan Masuk", "note": "Nota: Jika kata laluan pengurusan berasingan ditetapkan, sila masukkan; jika tidak, masukkan API_KEY.", - "lookup_hint": "Jika terlupa, jalankan docker logs antigravity-manager untuk mencari Current API Key atau Web UI Password", + "lookup_hint": "View gui_config.json or check environment variables to find them.", "config_hint": "Atau jalankan grep -E '\"api_key\"|\"admin_password\"' ~/.antigravity_tools/gui_config.json untuk melihat." }, "token_stats": { @@ -1084,4 +1084,4 @@ "hint_max_ips": "0 bermaksud tanpa had", "hint_curfew": "Biarkan kosong untuk nyahaktifkan. Berdasarkan masa pelayan." } -} \ No newline at end of file +} diff --git a/src/locales/pt.json b/src/locales/pt.json index cd92f22de..f9c7f0bea 100644 --- a/src/locales/pt.json +++ b/src/locales/pt.json @@ -1011,7 +1011,7 @@ "placeholder": "Insira a senha de administrador ou a Chave de API", "btn_login": "Verificar e Entrar", "note": "Nota: Se uma senha de administração separada estiver definida, insira-a; caso contrário, insira a API_KEY.", - "lookup_hint": "Se esqueceu, execute docker logs antigravity-manager para encontrar a Chave de API atual ou a senha da Web UI.", + "lookup_hint": "View gui_config.json or check environment variables to find them.", "config_hint": "Ou execute grep -E '\"api_key\"|\"admin_password\"' ~/.antigravity_tools/gui_config.json para visualizar." }, "errors": { @@ -1178,4 +1178,4 @@ "hint_max_ips": "0 significa ilimitado", "hint_curfew": "Deixe em branco para desativar. Baseado na hora do servidor." } -} \ No newline at end of file +} diff --git a/src/locales/ru.json b/src/locales/ru.json index a26934d57..4a751c415 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -1015,7 +1015,7 @@ "placeholder": "Введите пароль администратора или ключ API", "btn_login": "Проверить и войти", "note": "Примечание: если установлен отдельный пароль управления, введите его; в противном случае введите API_KEY.", - "lookup_hint": "Если вы забыли, запустите docker logs antigravity-manager, чтобы найти текущий ключ API или пароль Web UI.", + "lookup_hint": "View gui_config.json or check environment variables to find them.", "config_hint": "Или выполните grep -E '\"api_key\"|\"admin_password\"' ~/.antigravity_tools/gui_config.json для просмотра." }, "token_stats": { @@ -1173,4 +1173,4 @@ "hint_max_ips": "0 означает безлимитно", "hint_curfew": "Оставьте пустым, чтобы отключить. По времени сервера." } -} \ No newline at end of file +} diff --git a/src/locales/tr.json b/src/locales/tr.json index de4b8a4e9..a0a154f9e 100644 --- a/src/locales/tr.json +++ b/src/locales/tr.json @@ -989,7 +989,7 @@ "placeholder": "Yönetici parolasını veya API Anahtarını girin", "btn_login": "Doğrula ve Gir", "note": "Not: Ayarlanmış ayrı bir yönetici parolası varsa, lütfen onu girin; aksi takdirde API_KEY girin.", - "lookup_hint": "Unuttuysanız, Mevcut API Anahtarını veya Web Kullanıcı Arayüzü Parolasını bulmak için docker logs antigravity-manager komutunu çalıştırın.", + "lookup_hint": "View gui_config.json or check environment variables to find them.", "config_hint": "Veya görüntülemek için grep -E '\"api_key\"|\"admin_password\"' ~/.antigravity_tools/gui_config.json komutunu çalıştırın." }, "token_stats": { @@ -1147,4 +1147,4 @@ "hint_max_ips": "0 sınırsız demektir", "hint_curfew": "Devre dışı bırakmak için boş bırakın. Sunucu saatine göredir." } -} \ No newline at end of file +} diff --git a/src/locales/vi.json b/src/locales/vi.json index 7e0e5594c..3511f2bb0 100644 --- a/src/locales/vi.json +++ b/src/locales/vi.json @@ -1038,7 +1038,7 @@ "placeholder": "Nhập mật khẩu quản trị hoặc API Key", "btn_login": "Xác minh và Vào", "note": "Lưu ý: Nếu đã thiết lập mật khẩu quản trị riêng, vui lòng nhập mật khẩu đó; nếu không, hãy nhập API_KEY.", - "lookup_hint": "Nếu quên, hãy chạy lệnh docker logs antigravity-manager để tìm API Key hiện tại hoặc Mật khẩu Web UI.", + "lookup_hint": "View gui_config.json or check environment variables to find them.", "config_hint": "Hoặc chạy lệnh grep -E '\"api_key\"|\"admin_password\"' ~/.antigravity_tools/gui_config.json để xem." }, "token_stats": { @@ -1196,4 +1196,4 @@ "hint_max_ips": "0 nghĩa là không giới hạn", "hint_curfew": "Để trống để tắt. Dựa trên giờ máy chủ." } -} \ No newline at end of file +} diff --git a/src/locales/zh-TW.json b/src/locales/zh-TW.json index c81cfcf52..3fda25b57 100644 --- a/src/locales/zh-TW.json +++ b/src/locales/zh-TW.json @@ -1048,7 +1048,7 @@ "error_invalid_key": "密碼或 API Key 錯誤,請重試", "error_network": "網路連線失敗,請檢查服務是否正常運行", "note": "注意:如果設置了獨立的管理密碼,請輸入管理密碼;否則請輸入 API_KEY。", - "lookup_hint": "如果您忘記了,請運行 docker logs antigravity-manager 尋找 Current API Key 或 Web UI Password", + "lookup_hint": "请查看 gui_config.json 或检查环境变量以获取它们。", "config_hint": "或執行 grep -E '\"api_key\"|\"admin_password\"' ~/.antigravity_tools/gui_config.json 查看。" }, "token_stats": { @@ -1207,4 +1207,4 @@ "hint_max_ips": "0 表示不限制", "hint_curfew": "留空則禁用。基於伺服器時間。" } -} \ No newline at end of file +} diff --git a/src/locales/zh.json b/src/locales/zh.json index 748c27901..fefec5a40 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -1,1359 +1,1359 @@ -{ +{ "common": { - "loading": "加载中...", - "load_more": "加载更多", - "add": "添加", - "copy": "复制", - "action": "操作", - "save": "保存", - "saved": "保存成功", - "cancel": "取消", - "confirm": "确认", - "close": "关闭", - "delete": "删除", - "edit": "编辑", - "refresh": "刷新", - "refreshing": "刷新中...", - "export": "导出", - "import": "导入", - "success": "成功", - "error": "错误", - "unknown": "未知", - "warning": "警告", - "info": "提示", - "details": "详情", - "example": "示例", - "clear": "清除", - "clearing": "清理中...", - "prev_page": "上一页", - "next_page": "下一页", - "pagination_info": "显示第 {{start}} 到 {{end}} 条,共 {{total}} 条", - "per_page": "每页", - "items": "条", - "accounts": "个账号", - "enabled": "已启用", - "disabled": "已禁用", - "tauri_api_not_loaded": "Tauri API 未正确加载,请重启应用", - "environment_error": "环境错误: {{error}}", - "submit": "提交", - "update": "更新", - "load_failed": "加载失败", - "create_success": "创建成功", - "update_success": "更新成功", - "delete_success": "删除成功", - "copied": "已复制到剪贴板", - "reason": "原因", - "show_raw": "显示原始报文", - "show_parsed": "显示解析后" + "loading": "鍔犺浇涓?..", + "load_more": "鍔犺浇鏇村", + "add": "娣诲姞", + "copy": "澶嶅埗", + "action": "鎿嶄綔", + "save": "淇濆瓨", + "saved": "淇濆瓨鎴愬姛", + "cancel": "鍙栨秷", + "confirm": "纭", + "close": "鍏抽棴", + "delete": "鍒犻櫎", + "edit": "缂栬緫", + "refresh": "鍒锋柊", + "refreshing": "鍒锋柊涓?..", + "export": "瀵煎嚭", + "import": "瀵煎叆", + "success": "鎴愬姛", + "error": "閿欒", + "unknown": "鏈煡", + "warning": "璀﹀憡", + "info": "鎻愮ず", + "details": "璇︽儏", + "example": "绀轰緥", + "clear": "娓呴櫎", + "clearing": "娓呯悊涓?..", + "prev_page": "涓婁竴椤?, + "next_page": "涓嬩竴椤?, + "pagination_info": "鏄剧ず绗?{{start}} 鍒?{{end}} 鏉★紝鍏?{{total}} 鏉?, + "per_page": "姣忛〉", + "items": "鏉?, + "accounts": "涓处鍙?, + "enabled": "宸插惎鐢?, + "disabled": "宸茬鐢?, + "tauri_api_not_loaded": "Tauri API 鏈纭姞杞?璇烽噸鍚簲鐢?, + "environment_error": "鐜閿欒: {{error}}", + "submit": "鎻愪氦", + "update": "鏇存柊", + "load_failed": "鍔犺浇澶辫触", + "create_success": "鍒涘缓鎴愬姛", + "update_success": "鏇存柊鎴愬姛", + "delete_success": "鍒犻櫎鎴愬姛", + "copied": "宸插鍒跺埌鍓创鏉?, + "reason": "鍘熷洜", + "show_raw": "鏄剧ず鍘熷鎶ユ枃", + "show_parsed": "鏄剧ず瑙f瀽鍚? }, "nav": { - "dashboard": "仪表盘", - "accounts": "账号管理", - "proxy": "API 反代", - "call_records": "流量日志", - "token_stats": "Token 统计", - "security": "IP 管理", - "security_logs": "IP 日志", - "settings": "设置", - "theme_to_dark": "切换到深色模式", - "theme_to_light": "切换到浅色模式", - "switch_to_english": "切换到英文", - "switch_to_chinese": "切换到中文", - "switch_to_traditional_chinese": "切换到繁体中文", + "dashboard": "浠〃鐩?, + "accounts": "璐﹀彿绠$悊", + "proxy": "API 鍙嶄唬", + "call_records": "娴侀噺鏃ュ織", + "token_stats": "Token 缁熻", + "security": "IP 绠$悊", + "security_logs": "IP 鏃ュ織", + "settings": "璁剧疆", + "theme_to_dark": "鍒囨崲鍒版繁鑹叉ā寮?, + "theme_to_light": "鍒囨崲鍒版祬鑹叉ā寮?, + "switch_to_english": "鍒囨崲鍒拌嫳鏂?, + "switch_to_chinese": "鍒囨崲鍒颁腑鏂?, + "switch_to_traditional_chinese": "鍒囨崲鍒扮箒浣撲腑鏂?, "switch_to_english_short": "EN", "switch_to_chinese_short": "ZH", "switch_to_traditional_chinese_short": "TW", - "switch_to_japanese": "切换到日文", + "switch_to_japanese": "鍒囨崲鍒版棩鏂?, "switch_to_japanese_short": "JA", - "switch_to_turkish": "切换到土耳其文", + "switch_to_turkish": "鍒囨崲鍒板湡鑰冲叾鏂?, "switch_to_turkish_short": "TR", - "switch_to_vietnamese": "切换到越南文", + "switch_to_vietnamese": "鍒囨崲鍒拌秺鍗楁枃", "switch_to_vietnamese_short": "VI", - "switch_to_russian": "切换到俄文", + "switch_to_russian": "鍒囨崲鍒颁縿鏂?, "switch_to_russian_short": "RU", - "switch_to_portuguese": "切换到葡萄牙文", + "switch_to_portuguese": "鍒囨崲鍒拌憽钀勭墮鏂?, "switch_to_portuguese_short": "PT", - "switch_to_korean": "切换到韩语", + "switch_to_korean": "鍒囨崲鍒伴煩璇?, "switch_to_korean_short": "KO", - "switch_to_spanish": "切换到西班牙语", + "switch_to_spanish": "鍒囨崲鍒拌タ鐝墮璇?, "switch_to_spanish_short": "ES", - "switch_to_malay": "切换到马来语", + "switch_to_malay": "鍒囨崲鍒伴┈鏉ヨ", "switch_to_malay_short": "MY", - "user_token": "用户 Token", - "logout": "登出" + "user_token": "鐢ㄦ埛 Token", + "logout": "鐧诲嚭" }, "dashboard": { - "hello": "你好, 用户 👋", - "refresh_quota": "刷新配额", - "refreshing": "刷新中...", - "total_accounts": "总账号数", - "avg_gemini": "Gemini 平均配额", - "avg_gemini_image": "Gemini 绘图平均配额", - "avg_claude": "Claude 平均配额", - "low_quota_accounts": "低配额账号", - "quota_sufficient": "✓ 配额充足", - "quota_low": "⚠ 配额较低", - "quota_desc": "配额 < 20%", - "current_account": "当前账号", - "switch_account": "切换账号", - "no_active_account": "暂无活跃账号", - "best_accounts": "最佳账号推荐", - "best_account_recommendation": "最佳账号推荐", - "switch_best": "一键切换最佳", - "switch_successfully": "一键切换最佳", - "view_all_accounts": "查看所有账号", - "export_data": "导出账号数据", - "for_gemini": "用于 Gemini", - "for_claude": "用于 Claude", + "hello": "浣犲ソ, 鐢ㄦ埛 馃憢", + "refresh_quota": "鍒锋柊閰嶉", + "refreshing": "鍒锋柊涓?..", + "total_accounts": "鎬昏处鍙锋暟", + "avg_gemini": "Gemini 骞冲潎閰嶉", + "avg_gemini_image": "Gemini 缁樺浘骞冲潎閰嶉", + "avg_claude": "Claude 骞冲潎閰嶉", + "low_quota_accounts": "浣庨厤棰濊处鍙?, + "quota_sufficient": "鉁?閰嶉鍏呰冻", + "quota_low": "鈿?閰嶉杈冧綆", + "quota_desc": "閰嶉 < 20%", + "current_account": "褰撳墠璐﹀彿", + "switch_account": "鍒囨崲璐﹀彿", + "no_active_account": "鏆傛棤娲昏穬璐﹀彿", + "best_accounts": "鏈€浣宠处鍙锋帹鑽?, + "best_account_recommendation": "鏈€浣宠处鍙锋帹鑽?, + "switch_best": "涓€閿垏鎹㈡渶浣?, + "switch_successfully": "涓€閿垏鎹㈡渶浣?, + "view_all_accounts": "鏌ョ湅鎵€鏈夎处鍙?, + "export_data": "瀵煎嚭璐﹀彿鏁版嵁", + "for_gemini": "鐢ㄤ簬 Gemini", + "for_claude": "鐢ㄤ簬 Claude", "toast": { - "switch_success": "切换成功!", - "switch_error": "切换账号失败", - "refresh_success": "配额刷新成功", - "refresh_error": "刷新失败", - "export_no_accounts": "没有可导出的账号", - "export_success": "导出成功! 文件已保存至: {{path}}", - "export_error": "导出失败" + "switch_success": "鍒囨崲鎴愬姛!", + "switch_error": "鍒囨崲璐﹀彿澶辫触", + "refresh_success": "閰嶉鍒锋柊鎴愬姛", + "refresh_error": "鍒锋柊澶辫触", + "export_no_accounts": "娌℃湁鍙鍑虹殑璐﹀彿", + "export_success": "瀵煎嚭鎴愬姛! 鏂囦欢宸蹭繚瀛樿嚦: {{path}}", + "export_error": "瀵煎嚭澶辫触" } }, "accounts": { - "account": "账号", - "search_placeholder": "搜索邮箱...", - "all": "全部", - "available": "可用", - "low_quota": "低配额", + "account": "璐﹀彿", + "search_placeholder": "鎼滅储閭...", + "all": "鍏ㄩ儴", + "available": "鍙敤", + "low_quota": "浣庨厤棰?, "ultra": "ULTRA", "pro": "PRO", "free": "FREE", - "edit_label": "编辑标签", - "custom_label_placeholder": "输入自定义标签", - "label_updated": "标签已更新", - "add_account": "添加账号", - "refresh_all": "刷新所有", - "refresh_selected": "刷新 ({{count}})", - "export_selected": "导出 ({{count}})", - "import_json": "导入", - "import_success": "成功导入 {{count}} 个账号", - "import_partial": "导入完成: {{success}} 个成功, {{fail}} 个失败", - "import_fail": "导入失败: {{error}}", - "import_invalid_format": "无效的 JSON 格式,请确保文件包含 email 和 refresh_token 字段", - "delete_selected": "删除 ({{count}})", - "current": "当前", - "current_badge": "当前", - "disabled": "已禁用", - "disabled_tooltip": "账号已被禁用(例如 refresh_token 被撤销/过期)。重新授权或更新 Token 后可恢复。", - "proxy_disabled": "反代已禁用", - "proxy_disabled_tooltip": "此账号已被手动禁用反代功能,不参与 API 请求,但仍可在应用中使用", - "enable_proxy": "启用反代", - "disable_proxy": "禁用反代", - "enable_proxy_selected": "启用 ({{count}})", - "disable_proxy_selected": "禁用 ({{count}})", - "proxy_disabled_reason_manual": "用户手动禁用", - "proxy_disabled_reason_batch": "批量禁用", + "edit_label": "缂栬緫鏍囩", + "custom_label_placeholder": "杈撳叆鑷畾涔夋爣绛?, + "label_updated": "鏍囩宸叉洿鏂?, + "add_account": "娣诲姞璐﹀彿", + "refresh_all": "鍒锋柊鎵€鏈?, + "refresh_selected": "鍒锋柊 ({{count}})", + "export_selected": "瀵煎嚭 ({{count}})", + "import_json": "瀵煎叆", + "import_success": "鎴愬姛瀵煎叆 {{count}} 涓处鍙?, + "import_partial": "瀵煎叆瀹屾垚: {{success}} 涓垚鍔? {{fail}} 涓け璐?, + "import_fail": "瀵煎叆澶辫触: {{error}}", + "import_invalid_format": "鏃犳晥鐨?JSON 鏍煎紡锛岃纭繚鏂囦欢鍖呭惈 email 鍜?refresh_token 瀛楁", + "delete_selected": "鍒犻櫎 ({{count}})", + "current": "褰撳墠", + "current_badge": "褰撳墠", + "disabled": "宸茬鐢?, + "disabled_tooltip": "璐﹀彿宸茶绂佺敤锛堜緥濡?refresh_token 琚挙閿€/杩囨湡锛夈€傞噸鏂版巿鏉冩垨鏇存柊 Token 鍚庡彲鎭㈠銆?, + "proxy_disabled": "鍙嶄唬宸茬鐢?, + "proxy_disabled_tooltip": "姝よ处鍙峰凡琚墜鍔ㄧ鐢ㄥ弽浠e姛鑳?涓嶅弬涓?API 璇锋眰,浣嗕粛鍙湪搴旂敤涓娇鐢?, + "enable_proxy": "鍚敤鍙嶄唬", + "disable_proxy": "绂佺敤鍙嶄唬", + "enable_proxy_selected": "鍚敤 ({{count}})", + "disable_proxy_selected": "绂佺敤 ({{count}})", + "proxy_disabled_reason_manual": "鐢ㄦ埛鎵嬪姩绂佺敤", + "proxy_disabled_reason_batch": "鎵归噺绂佺敤", "forbidden": "403", "forbidden_badge": "403", - "forbidden_tooltip": "API 返回 403 Forbidden,账号无权使用 Gemini Code Assist", - "forbidden_msg": "账号无权限,已跳过自动刷新", + "forbidden_tooltip": "API 杩斿洖 403 Forbidden锛岃处鍙锋棤鏉冧娇鐢?Gemini Code Assist", + "forbidden_msg": "璐﹀彿鏃犳潈闄愶紝宸茶烦杩囪嚜鍔ㄥ埛鏂?, "status": { "forbidden": "403 Forbidden", - "disabled": "账号已禁用", - "proxy_disabled": "反代已禁用", - "validation_required": "账号需验证", - "risk_controlled": "风控/限流", - "oauth_reauth_required": "授权异常", - "violation_blocked": "由于违规被禁用" + "disabled": "璐﹀彿宸茬鐢?, + "proxy_disabled": "鍙嶄唬宸茬鐢?, + "validation_required": "璐﹀彿闇€楠岃瘉", + "risk_controlled": "椋庢帶/闄愭祦", + "oauth_reauth_required": "鎺堟潈寮傚父", + "violation_blocked": "鐢变簬杩濊琚鐢? }, - "error_details": "错误详情", - "error_status": "错误状态", - "error_time": "检测时间", - "view_error": "查看原因", - "click_to_verify": "点击去验证", - "copy_validation_url": "复制验证链接", - "validation_url_copied": "验证链接已复制到剪贴板", - "go_to_appeal": "前往申诉", - "copy_appeal_url": "复制申诉链接", + "error_details": "閿欒璇︽儏", + "error_status": "閿欒鐘舵€?, + "error_time": "妫€娴嬫椂闂?, + "view_error": "鏌ョ湅鍘熷洜", + "click_to_verify": "鐐瑰嚮鍘婚獙璇?, + "copy_validation_url": "澶嶅埗楠岃瘉閾炬帴", + "validation_url_copied": "楠岃瘉閾炬帴宸插鍒跺埌鍓创鏉?, + "go_to_appeal": "鍓嶅線鐢宠瘔", + "copy_appeal_url": "澶嶅埗鐢宠瘔閾炬帴", "fix_guide": { - "title": "终端一键自救指南 (解决部分 403 拦截)", - "step1_title": "🚀 终极杀招(最快方案)", - "step1_desc": "打开终端(Terminal),执行以下命令告诉 Google \"是我本人\",可解决部分 403 拦截:", - "step1_li1": "按回车执行,提示继续时输入 <1>Y。", - "step1_li2": "浏览器自动打开,选择账号并“允许”。", - "step1_li3": "看到 <1>You are now authenticated 即大功告成!", - "step2_title": "🧹 如果无效(清除缓存重来)", - "step2_li1_prefix": "先执行清除命令退出旧认证:", - "step2_li2_prefix": "再执行登录:", - "tips_title": "💡 常见建议", - "tip1": "若仍 403,尝试先在终端执行 <1>unset GOOGLE_APPLICATION_CREDENTIALS 重置环境变量。", - "tip2": "生产环境强烈建议改用 <1>服务账户 (Service Account) 的 JSON 密钥,更稳定且免交互。", - "tip3": "若操作失败,请前往 <1>Google Cloud Console 中的 Generative Language API 查看是否被冻结权限。若是,说明账号触发了风控,建议让账号冷却 72 小时后再次尝试。", - "tip4": "你也可以尝试执行 <1>npm install -g @google/gemini-cli,只要不弹出错误,大概率在软件内删除账号重新授权即可。" + "title": "缁堢涓€閿嚜鏁戞寚鍗?(瑙e喅閮ㄥ垎 403 鎷︽埅)", + "step1_title": "馃殌 缁堟瀬鏉€鎷涳紙鏈€蹇柟妗堬級", + "step1_desc": "鎵撳紑缁堢锛圱erminal锛夛紝鎵ц浠ヤ笅鍛戒护鍛婅瘔 Google \"鏄垜鏈汉\"锛屽彲瑙e喅閮ㄥ垎 403 鎷︽埅锛?, + "step1_li1": "鎸夊洖杞︽墽琛岋紝鎻愮ず缁х画鏃惰緭鍏?<1>Y銆?, + "step1_li2": "娴忚鍣ㄨ嚜鍔ㄦ墦寮€锛岄€夋嫨璐﹀彿骞垛€滃厑璁糕€濄€?, + "step1_li3": "鐪嬪埌 <1>You are now authenticated 鍗冲ぇ鍔熷憡鎴愶紒", + "step2_title": "馃Ч 濡傛灉鏃犳晥锛堟竻闄ょ紦瀛橀噸鏉ワ級", + "step2_li1_prefix": "鍏堟墽琛屾竻闄ゅ懡浠ら€€鍑烘棫璁よ瘉锛?, + "step2_li2_prefix": "鍐嶆墽琛岀櫥褰曪細", + "tips_title": "馃挕 甯歌寤鸿", + "tip1": "鑻ヤ粛 403锛屽皾璇曞厛鍦ㄧ粓绔墽琛?<1>unset GOOGLE_APPLICATION_CREDENTIALS 閲嶇疆鐜鍙橀噺銆?, + "tip2": "鐢熶骇鐜寮虹儓寤鸿鏀圭敤 <1>鏈嶅姟璐︽埛 (Service Account) 鐨?JSON 瀵嗛挜锛屾洿绋冲畾涓斿厤浜や簰銆?, + "tip3": "鑻ユ搷浣滃け璐ワ紝璇峰墠寰€ <1>Google Cloud Console 涓殑 Generative Language API 鏌ョ湅鏄惁琚喕缁撴潈闄愩€傝嫢鏄紝璇存槑璐﹀彿瑙﹀彂浜嗛鎺э紝寤鸿璁╄处鍙峰喎鍗?72 灏忔椂鍚庡啀娆″皾璇曘€?, + "tip4": "浣犱篃鍙互灏濊瘯鎵ц <1>npm install -g @google/gemini-cli锛屽彧瑕佷笉寮瑰嚭閿欒锛屽ぇ姒傜巼鍦ㄨ蒋浠跺唴鍒犻櫎璐﹀彿閲嶆柊鎺堟潈鍗冲彲銆? }, - "no_data": "无数据", - "last_used": "最后使用", - "reset_time": "重置时间", - "switch_to": "切换到此账号", - "switch_to_classic": "切换到 Antigravity (经典版)", - "switch_to_ide": "切换到 Antigravity IDE", - "actions": "操作", - "device_fingerprint": "设备指纹", - "show_all_quotas": "显示所有配额", + "no_data": "鏃犳暟鎹?, + "last_used": "鏈€鍚庝娇鐢?, + "reset_time": "閲嶇疆鏃堕棿", + "switch_to": "鍒囨崲鍒版璐﹀彿", + "switch_to_classic": "鍒囨崲鍒?Antigravity (缁忓吀鐗?", + "switch_to_ide": "鍒囨崲鍒?Antigravity IDE", + "actions": "鎿嶄綔", + "device_fingerprint": "璁惧鎸囩汗", + "show_all_quotas": "鏄剧ず鎵€鏈夐厤棰?, "device_fingerprint_dialog": { - "title": "设备指纹", - "operations": "设备指纹操作", - "generate_and_bind": "生成并绑定", - "restore_original": "恢复原始", - "open_storage_directory": "打开存储目录", - "current_storage": "当前存储", - "effective": "已生效", - "current_storage_desc": "读取自 storage.json(切换账号时应用绑定后更新)", - "account_binding": "账号绑定", - "pending_application": "待应用", - "account_binding_desc": "生成/恢复后保存为绑定,切换账号时写入 storage.json", - "historical_fingerprints": "历史指纹(可选恢复/删除)", - "no_history": "暂无历史", - "current": "当前", - "restore": "恢复", - "delete_version": "删除此版本", - "confirm_generate_title": "确认生成并绑定?", - "confirm_generate_desc": "将生成一套新的设备指纹并设置为当前指纹。确认继续?", - "confirm_restore_title": "确认恢复原始指纹?", - "confirm_restore_desc": "将恢复为原始指纹并覆盖当前指纹。确认继续?", - "cancel": "取消", - "confirm": "确认", - "processing": "处理中...", - "loading": "加载中...", - "failed_to_load_device_info": "加载设备信息失败", - "generation_failed": "生成失败", - "binding_failed": "绑定失败", - "restoration_failed": "恢复失败", - "deletion_failed": "删除失败", - "directory_open_failed": "无法打开目录", - "generated_and_bound": "已生成并绑定", - "restored": "已恢复", - "deleted": "已删除", - "directory_opened": "已打开设备存储目录", - "original_fingerprint_not_found": "未找到原始指纹" + "title": "璁惧鎸囩汗", + "operations": "璁惧鎸囩汗鎿嶄綔", + "generate_and_bind": "鐢熸垚骞剁粦瀹?, + "restore_original": "鎭㈠鍘熷", + "open_storage_directory": "鎵撳紑瀛樺偍鐩綍", + "current_storage": "褰撳墠瀛樺偍", + "effective": "宸茬敓鏁?, + "current_storage_desc": "璇诲彇鑷?storage.json锛堝垏鎹㈣处鍙锋椂搴旂敤缁戝畾鍚庢洿鏂帮級", + "account_binding": "璐﹀彿缁戝畾", + "pending_application": "寰呭簲鐢?, + "account_binding_desc": "鐢熸垚/鎭㈠鍚庝繚瀛樹负缁戝畾锛屽垏鎹㈣处鍙锋椂鍐欏叆 storage.json", + "historical_fingerprints": "鍘嗗彶鎸囩汗锛堝彲閫夋仮澶?鍒犻櫎锛?, + "no_history": "鏆傛棤鍘嗗彶", + "current": "褰撳墠", + "restore": "鎭㈠", + "delete_version": "鍒犻櫎姝ょ増鏈?, + "confirm_generate_title": "纭鐢熸垚骞剁粦瀹氾紵", + "confirm_generate_desc": "灏嗙敓鎴愪竴濂楁柊鐨勮澶囨寚绾瑰苟璁剧疆涓哄綋鍓嶆寚绾广€傜‘璁ょ户缁紵", + "confirm_restore_title": "纭鎭㈠鍘熷鎸囩汗锛?, + "confirm_restore_desc": "灏嗘仮澶嶄负鍘熷鎸囩汗骞惰鐩栧綋鍓嶆寚绾广€傜‘璁ょ户缁紵", + "cancel": "鍙栨秷", + "confirm": "纭", + "processing": "澶勭悊涓?..", + "loading": "鍔犺浇涓?..", + "failed_to_load_device_info": "鍔犺浇璁惧淇℃伅澶辫触", + "generation_failed": "鐢熸垚澶辫触", + "binding_failed": "缁戝畾澶辫触", + "restoration_failed": "鎭㈠澶辫触", + "deletion_failed": "鍒犻櫎澶辫触", + "directory_open_failed": "鏃犳硶鎵撳紑鐩綍", + "generated_and_bound": "宸茬敓鎴愬苟缁戝畾", + "restored": "宸叉仮澶?, + "deleted": "宸插垹闄?, + "directory_opened": "宸叉墦寮€璁惧瀛樺偍鐩綍", + "original_fingerprint_not_found": "鏈壘鍒板師濮嬫寚绾? }, - "warmup_all": "一键预热", - "warmup_selected": "预热 ({{count}})", - "warmup_this": "预热该账号", - "warmup_now": "立即预热", - "warmup_batch_triggered": "已成功为 {{count}} 个账号触发预热任务", - "quota_protected": "受保护", + "warmup_all": "涓€閿鐑?, + "warmup_selected": "棰勭儹 ({{count}})", + "warmup_this": "棰勭儹璇ヨ处鍙?, + "warmup_now": "绔嬪嵆棰勭儹", + "warmup_batch_triggered": "宸叉垚鍔熶负 {{count}} 涓处鍙疯Е鍙戦鐑换鍔?, + "quota_protected": "鍙椾繚鎶?, "details": { - "title": "配额详情", - "model_quota": "模型配额", - "protected_models": "受保护模型" + "title": "閰嶉璇︽儏", + "model_quota": "妯″瀷閰嶉", + "protected_models": "鍙椾繚鎶ゆā鍨? }, "toast": { - "proxy_enabled": "成功启用 {{count}} 个账号的反代功能", - "proxy_disabled": "成功禁用 {{count}} 个账号的反代功能" + "proxy_enabled": "鎴愬姛鍚敤 {{count}} 涓处鍙风殑鍙嶄唬鍔熻兘", + "proxy_disabled": "鎴愬姛绂佺敤 {{count}} 涓处鍙风殑鍙嶄唬鍔熻兘" }, "add": { - "title": "添加新账号", + "title": "娣诲姞鏂拌处鍙?, "tabs": { - "oauth": "OAuth 授权", + "oauth": "OAuth 鎺堟潈", "token": "Refresh Token", - "import": "从数据库导入" + "import": "浠庢暟鎹簱瀵煎叆" }, "oauth": { - "recommend": "推荐方式", - "desc": "将打开默认浏览器进行 Google 登录授权,自动获取并保存 Token。", - "btn_start": "开始 OAuth 授权", - "btn_waiting": "正在等待授权...", - "btn_finish": "我已授权,继续", - "copy_link": "复制授权链接", - "copied": "已复制", - "link_label": "授权链接", - "link_click_to_copy": "点击复制", - "manual_hint": "浏览器没有自动跳转?请在此处粘贴回调链接或 Authorization Code:", - "manual_placeholder": "粘贴回调链接或 Code...", - "error_no_flow": "请先点击“开始 OAuth 授权”", - "web_hint": "将在新窗口中打开 Google 登录页", - "error_no_url": "无法获取 OAuth URL", - "popup_blocked": "弹窗被拦截,请允许弹出窗口", - "manual_submitting": "正在提交认证码...", - "manual_submitted": "认证码已提交,后台处理中..." + "recommend": "鎺ㄨ崘鏂瑰紡", + "desc": "灏嗘墦寮€榛樿娴忚鍣ㄨ繘琛?Google 鐧诲綍鎺堟潈锛岃嚜鍔ㄨ幏鍙栧苟淇濆瓨 Token銆?, + "btn_start": "寮€濮?OAuth 鎺堟潈", + "btn_waiting": "姝e湪绛夊緟鎺堟潈...", + "btn_finish": "鎴戝凡鎺堟潈锛岀户缁?, + "copy_link": "澶嶅埗鎺堟潈閾炬帴", + "copied": "宸插鍒?, + "link_label": "鎺堟潈閾炬帴", + "link_click_to_copy": "鐐瑰嚮澶嶅埗", + "manual_hint": "娴忚鍣ㄦ病鏈夎嚜鍔ㄨ烦杞紵璇峰湪姝ゅ绮樿创鍥炶皟閾炬帴鎴?Authorization Code锛?, + "manual_placeholder": "绮樿创鍥炶皟閾炬帴鎴?Code...", + "error_no_flow": "璇峰厛鐐瑰嚮鈥滃紑濮?OAuth 鎺堟潈鈥?, + "web_hint": "灏嗗湪鏂扮獥鍙d腑鎵撳紑 Google 鐧诲綍椤?, + "error_no_url": "鏃犳硶鑾峰彇 OAuth URL", + "popup_blocked": "寮圭獥琚嫤鎴紝璇峰厑璁稿脊鍑虹獥鍙?, + "manual_submitting": "姝e湪鎻愪氦璁よ瘉鐮?..", + "manual_submitted": "璁よ瘉鐮佸凡鎻愪氦锛屽悗鍙板鐞嗕腑..." }, "token": { "label": "Refresh Token", - "placeholder": "在此处粘贴您的 Refresh Token (支持批量)\n\n支持格式:\n1. 单个 Token (1//...)\n2. JSON 数组 (含 refresh_token 字段)\n3. 任意包含 Token 的文本 (自动提取)", - "hint": "提示: 支持一次性粘贴多个 Token 或 JSON 数组,系统将自动识别并批量导入。", - "error_token": "请填写 Refresh Token", - "batch_progress": "正在导入第 {{current}}/{{total}} 个账户...", - "batch_success": "成功导入 {{count}} 个账户", - "batch_partial": "导入完成: {{success}} 个成功, {{fail}} 个失败", - "batch_fail": "导入失败" + "placeholder": "鍦ㄦ澶勭矘璐存偍鐨?Refresh Token (鏀寔鎵归噺)\n\n鏀寔鏍煎紡:\n1. 鍗曚釜 Token (1//...)\n2. JSON 鏁扮粍 (鍚?refresh_token 瀛楁)\n3. 浠绘剰鍖呭惈 Token 鐨勬枃鏈?(鑷姩鎻愬彇)", + "hint": "鎻愮ず: 鏀寔涓€娆℃€х矘璐村涓?Token 鎴?JSON 鏁扮粍锛岀郴缁熷皢鑷姩璇嗗埆骞舵壒閲忓鍏ャ€?, + "error_token": "璇峰~鍐?Refresh Token", + "batch_progress": "姝e湪瀵煎叆绗?{{current}}/{{total}} 涓处鎴?..", + "batch_success": "鎴愬姛瀵煎叆 {{count}} 涓处鎴?, + "batch_partial": "瀵煎叆瀹屾垚: {{success}} 涓垚鍔? {{fail}} 涓け璐?, + "batch_fail": "瀵煎叆澶辫触" }, "import": { - "scheme_a": "方案 A: 从当前 IDE 数据库", - "scheme_a_desc": "自动从本地 Antigravity 数据库读取当前登录的账号信息。", - "btn_db": "导入当前登录账号", - "or": "或者", - "scheme_b": "方案 B: 从 V1 版本备份", - "scheme_b_desc": "扫描 ~/.antigravity-agent 目录,批量导入旧版本的账号数据。", - "btn_v1": "从 V1 备份批量导入", - "btn_custom_db": "从自定义 DB 导入" + "scheme_a": "鏂规 A: 浠庡綋鍓?IDE 鏁版嵁搴?, + "scheme_a_desc": "鑷姩浠庢湰鍦?Antigravity 鏁版嵁搴撹鍙栧綋鍓嶇櫥褰曠殑璐﹀彿淇℃伅銆?, + "btn_db": "瀵煎叆褰撳墠鐧诲綍璐﹀彿", + "or": "鎴栬€?, + "scheme_b": "鏂规 B: 浠?V1 鐗堟湰澶囦唤", + "scheme_b_desc": "鎵弿 ~/.antigravity-agent 鐩綍锛屾壒閲忓鍏ユ棫鐗堟湰鐨勮处鍙锋暟鎹€?, + "btn_v1": "浠?V1 澶囦唤鎵归噺瀵煎叆", + "btn_custom_db": "浠庤嚜瀹氫箟 DB 瀵煎叆" }, - "btn_cancel": "取消", - "btn_confirm": "确认添加", - "oauth_error": "OAuth 授权失败: {{error}}", + "btn_cancel": "鍙栨秷", + "btn_confirm": "纭娣诲姞", + "oauth_error": "OAuth 鎺堟潈澶辫触: {{error}}", "status": { - "error_token": "请填写 Refresh Token" + "error_token": "璇峰~鍐?Refresh Token" } }, "table": { - "email": "邮箱", - "quota": "模型配额", - "last_used": "最后使用", - "actions": "操作" + "email": "閭", + "quota": "妯″瀷閰嶉", + "last_used": "鏈€鍚庝娇鐢?, + "actions": "鎿嶄綔" }, - "drag_to_reorder": "拖拽排序", + "drag_to_reorder": "鎷栨嫿鎺掑簭", "empty": { - "title": "暂无账号", - "desc": "点击上方\"添加账号\"按钮添加第一个账号" + "title": "鏆傛棤璐﹀彿", + "desc": "鐐瑰嚮涓婃柟\"娣诲姞璐﹀彿\"鎸夐挳娣诲姞绗竴涓处鍙? }, "views": { - "list": "列表视图", - "grid": "网格视图" + "list": "鍒楄〃瑙嗗浘", + "grid": "缃戞牸瑙嗗浘" }, "dialog": { - "add_title": "添加新账号", - "batch_delete_title": "批量删除确认", - "delete_title": "删除确认", - "batch_delete_msg": "确定要删除选中的 {{count}} 个账号吗?此操作无法撤销。", - "delete_msg": "确定要删除这个账号吗?此操作无法撤销。", - "refresh_title": "刷新配额", - "batch_refresh_title": "批量刷新", - "refresh_msg": "确定要刷新当前账号的配额吗?", - "batch_refresh_msg": "确定要刷新选中的 {{count}} 个账号的配额吗?这可能需要一些时间。", - "disable_proxy_title": "禁用反代", - "disable_proxy_msg": "确定要禁用此账号的反代功能吗?账号仍可在应用中使用。", - "enable_proxy_title": "启用反代", - "enable_proxy_msg": "确定要重新启用此账号的反代功能吗?", - "warmup_all_title": "全量手动预热", - "warmup_all_msg": "确定要立即为所有符合条件的账号触发预热任务吗?这将向 Google 服务发送极小流量以重置配额配额周期。", - "batch_warmup_title": "批量手动预热", - "batch_warmup_msg": "确定要为选中的 {{count}} 个账号立即触发预热吗?" + "add_title": "娣诲姞鏂拌处鍙?, + "batch_delete_title": "鎵归噺鍒犻櫎纭", + "delete_title": "鍒犻櫎纭", + "batch_delete_msg": "纭畾瑕佸垹闄ら€変腑鐨?{{count}} 涓处鍙峰悧锛熸鎿嶄綔鏃犳硶鎾ら攢銆?, + "delete_msg": "纭畾瑕佸垹闄よ繖涓处鍙峰悧锛熸鎿嶄綔鏃犳硶鎾ら攢銆?, + "refresh_title": "鍒锋柊閰嶉", + "batch_refresh_title": "鎵归噺鍒锋柊", + "refresh_msg": "纭畾瑕佸埛鏂板綋鍓嶈处鍙风殑閰嶉鍚楋紵", + "batch_refresh_msg": "纭畾瑕佸埛鏂伴€変腑鐨?{{count}} 涓处鍙风殑閰嶉鍚楋紵杩欏彲鑳介渶瑕佷竴浜涙椂闂淬€?, + "disable_proxy_title": "绂佺敤鍙嶄唬", + "disable_proxy_msg": "纭畾瑕佺鐢ㄦ璐﹀彿鐨勫弽浠e姛鑳藉悧锛熻处鍙蜂粛鍙湪搴旂敤涓娇鐢ㄣ€?, + "enable_proxy_title": "鍚敤鍙嶄唬", + "enable_proxy_msg": "纭畾瑕侀噸鏂板惎鐢ㄦ璐﹀彿鐨勫弽浠e姛鑳藉悧锛?, + "warmup_all_title": "鍏ㄩ噺鎵嬪姩棰勭儹", + "warmup_all_msg": "纭畾瑕佺珛鍗充负鎵€鏈夌鍚堟潯浠剁殑璐﹀彿瑙﹀彂棰勭儹浠诲姟鍚楋紵杩欏皢鍚?Google 鏈嶅姟鍙戦€佹瀬灏忔祦閲忎互閲嶇疆閰嶉閰嶉鍛ㄦ湡銆?, + "batch_warmup_title": "鎵归噺鎵嬪姩棰勭儹", + "batch_warmup_msg": "纭畾瑕佷负閫変腑鐨?{{count}} 涓处鍙风珛鍗宠Е鍙戦鐑悧锛? } }, "settings": { - "save": "保存设置", + "save": "淇濆瓨璁剧疆", "tabs": { - "general": "通用", - "account": "账号", - "proxy": "代理设置", - "advanced": "高级", - "debug": "调试", - "about": "关于" + "general": "閫氱敤", + "account": "璐﹀彿", + "proxy": "浠g悊璁剧疆", + "advanced": "楂樼骇", + "debug": "璋冭瘯", + "about": "鍏充簬" }, "general": { - "title": "通用设置", - "language": "语言", - "theme": "主题", - "theme_light": "浅色", - "theme_dark": "深色", - "theme_system": "跟随系统", - "auto_launch": "开机自动启动", - "auto_launch_enabled": "启用", - "auto_launch_disabled": "禁用", - "auto_launch_desc": "系统启动时自动运行 Antigravity Tools", - "auto_check_update": "自动检查更新", - "auto_check_update_desc": "启动时自动检查新版本", - "auto_check_update_enabled": "已启用自动检查更新", - "auto_check_update_disabled": "已禁用自动检查更新", - "update_check_interval": "检查间隔(小时)", - "update_check_interval_desc": "设置自动检查更新的时间间隔(1-168 小时)", - "update_check_interval_saved": "已保存检查间隔设置" + "title": "閫氱敤璁剧疆", + "language": "璇█", + "theme": "涓婚", + "theme_light": "娴呰壊", + "theme_dark": "娣辫壊", + "theme_system": "璺熼殢绯荤粺", + "auto_launch": "寮€鏈鸿嚜鍔ㄥ惎鍔?, + "auto_launch_enabled": "鍚敤", + "auto_launch_disabled": "绂佺敤", + "auto_launch_desc": "绯荤粺鍚姩鏃惰嚜鍔ㄨ繍琛?Antigravity Tools", + "auto_check_update": "鑷姩妫€鏌ユ洿鏂?, + "auto_check_update_desc": "鍚姩鏃惰嚜鍔ㄦ鏌ユ柊鐗堟湰", + "auto_check_update_enabled": "宸插惎鐢ㄨ嚜鍔ㄦ鏌ユ洿鏂?, + "auto_check_update_disabled": "宸茬鐢ㄨ嚜鍔ㄦ鏌ユ洿鏂?, + "update_check_interval": "妫€鏌ラ棿闅?灏忔椂)", + "update_check_interval_desc": "璁剧疆鑷姩妫€鏌ユ洿鏂扮殑鏃堕棿闂撮殧(1-168 灏忔椂)", + "update_check_interval_saved": "宸蹭繚瀛樻鏌ラ棿闅旇缃? }, "account": { - "title": "账号设置", - "auto_refresh": "后台自动刷新", - "auto_refresh_desc": "后台自动刷新所有账号的配额信息,这是额度保护和智能预热的基础。", - "always_on": "始终开启", - "refresh_interval": "刷新间隔(分钟)", - "auto_sync": "自动获取当前账号", - "auto_sync_desc": "定期自动刷新当前活动账号的信息", - "sync_interval": "同步间隔(分钟)" + "title": "璐﹀彿璁剧疆", + "auto_refresh": "鍚庡彴鑷姩鍒锋柊", + "auto_refresh_desc": "鍚庡彴鑷姩鍒锋柊鎵€鏈夎处鍙风殑閰嶉淇℃伅锛岃繖鏄搴︿繚鎶ゅ拰鏅鸿兘棰勭儹鐨勫熀纭€銆?, + "always_on": "濮嬬粓寮€鍚?, + "refresh_interval": "鍒锋柊闂撮殧锛堝垎閽燂級", + "auto_sync": "鑷姩鑾峰彇褰撳墠璐﹀彿", + "auto_sync_desc": "瀹氭湡鑷姩鍒锋柊褰撳墠娲诲姩璐﹀彿鐨勪俊鎭?, + "sync_interval": "鍚屾闂撮殧锛堝垎閽燂級" }, "warmup": { - "title": "智能预热", - "desc": "自动监控所有模型,当额度恢复到 100% 时立即触发预热,保持模型热状态" + "title": "鏅鸿兘棰勭儹", + "desc": "鑷姩鐩戞帶鎵€鏈夋ā鍨嬶紝褰撻搴︽仮澶嶅埌 100% 鏃剁珛鍗宠Е鍙戦鐑紝淇濇寔妯″瀷鐑姸鎬? }, "quota_protection": { - "title": "配额保护", - "enable": "启用配额保护", - "enable_desc": "当账号剩余配额低于阈值时自动禁用反代功能,配额重置后将自动恢复账号", - "threshold_label": "保留配额百分比", - "monitored_models_label": "监控模型 (触发条件)", - "monitored_models_desc": "至少选择一个核心模型。任一勾选模型额度低于阈值将触发保护", - "range": "范围", - "example": "示例:设置 {{percentage}}% 时,{{total}} 次配额的账号剩余 ≤ {{threshold}} 次时将被自动禁用", - "auto_restore_info": "配额重置后将自动重新启用账号" + "title": "閰嶉淇濇姢", + "enable": "鍚敤閰嶉淇濇姢", + "enable_desc": "褰撹处鍙峰墿浣欓厤棰濅綆浜庨槇鍊兼椂鑷姩绂佺敤鍙嶄唬鍔熻兘锛岄厤棰濋噸缃悗灏嗚嚜鍔ㄦ仮澶嶈处鍙?, + "threshold_label": "淇濈暀閰嶉鐧惧垎姣?, + "monitored_models_label": "鐩戞帶妯″瀷 (瑙﹀彂鏉′欢)", + "monitored_models_desc": "鑷冲皯閫夋嫨涓€涓牳蹇冩ā鍨嬨€備换涓€鍕鹃€夋ā鍨嬮搴︿綆浜庨槇鍊煎皢瑙﹀彂淇濇姢", + "range": "鑼冨洿", + "example": "绀轰緥锛氳缃?{{percentage}}% 鏃讹紝{{total}} 娆¢厤棰濈殑璐﹀彿鍓╀綑 鈮?{{threshold}} 娆℃椂灏嗚鑷姩绂佺敤", + "auto_restore_info": "閰嶉閲嶇疆鍚庡皢鑷姩閲嶆柊鍚敤璐﹀彿" }, "pinned_quota_models": { - "title": "配额关注列表", - "desc": "选择要在账号列表外层显示的模型配额,未选中的模型只在详情弹窗中显示" + "title": "閰嶉鍏虫敞鍒楄〃", + "desc": "閫夋嫨瑕佸湪璐﹀彿鍒楄〃澶栧眰鏄剧ず鐨勬ā鍨嬮厤棰濓紝鏈€変腑鐨勬ā鍨嬪彧鍦ㄨ鎯呭脊绐椾腑鏄剧ず" }, "proxy": { - "title": "代理设置" + "title": "浠g悊璁剧疆" }, "proxy_pool": { - "title": "代理池", - "strategy_priority": "按权重随机", - "strategy_round_robin": "顺序循环", - "strategy_random": "随机", - "strategy_least_connections": "最少连接", - "test_all": "全量检测", - "batch_import": "导入", - "binding_manager": "绑定", - "add_proxy": "添加代理", - "edit_proxy": "编辑代理", - "name": "名称", - "url": "代理地址", - "username": "用户名", - "password": "密码", - "max_accounts": "最大账号数", - "max_accounts_hint": "0 = 不限制", - "priority": "优先级", - "priority_hint": "越小越优先", - "health_check_url": "健康检查地址", - "tags": "标签", - "add_tag_placeholder": "添加标签...", - "seconds": "秒", - "interval_tooltip": "健康检查间隔 (秒)", - "test_completed": "健康检查已完成", - "test_failed": "健康检查失败", - "confirm_delete": "确定要删除此代理吗?", - "empty": "暂无代理", - "column_priority": "权重", - "column_status": "状态", - "column_details": "代理详情", - "column_bindings": "绑定", - "import_title": "批量导入代理", - "import_label": "粘贴代理列表 (每行一个)", - "import_hint": "支持格式: protocol://user:pass@host:port, host:port:user:pass", - "import_preview": "预览", - "import_confirm": "导入 {{count}} 个代理", - "no_valid_proxies": "未找到有效代理", + "title": "浠g悊姹?, + "strategy_priority": "鎸夋潈閲嶉殢鏈?, + "strategy_round_robin": "椤哄簭寰幆", + "strategy_random": "闅忔満", + "strategy_least_connections": "鏈€灏戣繛鎺?, + "test_all": "鍏ㄩ噺妫€娴?, + "batch_import": "瀵煎叆", + "binding_manager": "缁戝畾", + "add_proxy": "娣诲姞浠g悊", + "edit_proxy": "缂栬緫浠g悊", + "name": "鍚嶇О", + "url": "浠g悊鍦板潃", + "username": "鐢ㄦ埛鍚?, + "password": "瀵嗙爜", + "max_accounts": "鏈€澶ц处鍙锋暟", + "max_accounts_hint": "0 = 涓嶉檺鍒?, + "priority": "浼樺厛绾?, + "priority_hint": "瓒婂皬瓒婁紭鍏?, + "health_check_url": "鍋ュ悍妫€鏌ュ湴鍧€", + "tags": "鏍囩", + "add_tag_placeholder": "娣诲姞鏍囩...", + "seconds": "绉?, + "interval_tooltip": "鍋ュ悍妫€鏌ラ棿闅?(绉?", + "test_completed": "鍋ュ悍妫€鏌ュ凡瀹屾垚", + "test_failed": "鍋ュ悍妫€鏌ュけ璐?, + "confirm_delete": "纭畾瑕佸垹闄ゆ浠g悊鍚楋紵", + "empty": "鏆傛棤浠g悊", + "column_priority": "鏉冮噸", + "column_status": "鐘舵€?, + "column_details": "浠g悊璇︽儏", + "column_bindings": "缁戝畾", + "import_title": "鎵归噺瀵煎叆浠g悊", + "import_label": "绮樿创浠g悊鍒楄〃 (姣忚涓€涓?", + "import_hint": "鏀寔鏍煎紡: protocol://user:pass@host:port, host:port:user:pass", + "import_preview": "棰勮", + "import_confirm": "瀵煎叆 {{count}} 涓唬鐞?, + "no_valid_proxies": "鏈壘鍒版湁鏁堜唬鐞?, "binding": { - "title": "账号代理绑定", - "load_failed": "加载绑定失败", - "unbind_success": "解绑成功", - "bind_success": "绑定成功", - "update_failed": "更新绑定失败", - "assigned_proxy": "已分配代理", - "default_strategy": "默认 (跟随策略)" + "title": "璐﹀彿浠g悊缁戝畾", + "load_failed": "鍔犺浇缁戝畾澶辫触", + "unbind_success": "瑙g粦鎴愬姛", + "bind_success": "缁戝畾鎴愬姛", + "update_failed": "鏇存柊缁戝畾澶辫触", + "assigned_proxy": "宸插垎閰嶄唬鐞?, + "default_strategy": "榛樿 (璺熼殢绛栫暐)" }, "status": { - "inactive": "未启用", - "checking": "正在检测", - "healthy": "正常", - "timeout": "已超时" + "inactive": "鏈惎鐢?, + "checking": "姝e湪妫€娴?, + "healthy": "姝e父", + "timeout": "宸茶秴鏃? } }, "advanced": { - "title": "高级设置", - "export_path": "默认导出路径", - "export_path_placeholder": "未设置 (每次询问)", - "default_export_path_desc": "设置后,导出文件将直接保存到该目录,不再弹出选择框", - "select_btn": "选择", - "open_btn": "打开", - "data_dir": "数据目录", - "data_dir_desc": "账号数据和配置文件的存储位置", - "antigravity_path": "反重力程序路径", - "antigravity_path_placeholder": "未设置 (将使用自动探测)", - "antigravity_path_desc": "如果您将 Antigravity 应用安装在非标准位置,可在此手动指定可执行文件路径(MacOS 指向 .app 目录)。", - "antigravity_path_select": "选择反重力程序可执行文件", - "antigravity_path_detected": "已更新探测到的路径", - "antigravity_ide_path": "Antigravity IDE 路径", + "title": "楂樼骇璁剧疆", + "export_path": "榛樿瀵煎嚭璺緞", + "export_path_placeholder": "鏈缃?(姣忔璇㈤棶)", + "default_export_path_desc": "璁剧疆鍚庯紝瀵煎嚭鏂囦欢灏嗙洿鎺ヤ繚瀛樺埌璇ョ洰褰曪紝涓嶅啀寮瑰嚭閫夋嫨妗?, + "select_btn": "閫夋嫨", + "open_btn": "鎵撳紑", + "data_dir": "鏁版嵁鐩綍", + "data_dir_desc": "璐﹀彿鏁版嵁鍜岄厤缃枃浠剁殑瀛樺偍浣嶇疆", + "antigravity_path": "鍙嶉噸鍔涚▼搴忚矾寰?, + "antigravity_path_placeholder": "鏈缃?(灏嗕娇鐢ㄨ嚜鍔ㄦ帰娴?", + "antigravity_path_desc": "濡傛灉鎮ㄥ皢 Antigravity 搴旂敤瀹夎鍦ㄩ潪鏍囧噯浣嶇疆锛屽彲鍦ㄦ鎵嬪姩鎸囧畾鍙墽琛屾枃浠惰矾寰勶紙MacOS 鎸囧悜 .app 鐩綍锛夈€?, + "antigravity_path_select": "閫夋嫨鍙嶉噸鍔涚▼搴忓彲鎵ц鏂囦欢", + "antigravity_path_detected": "宸叉洿鏂版帰娴嬪埌鐨勮矾寰?, + "antigravity_ide_path": "Antigravity IDE 璺緞", "antigravity_ide_path_placeholder": "D:\\Antigravity\\Antigravity.exe", - "antigravity_ide_path_desc": "指定 Antigravity IDE (代码编辑器) 的可执行文件路径。设置后,切换账号时将严格保护此路径的进程不被关闭。", - "antigravity_ide_path_select": "选择 Antigravity IDE 可执行文件", - "detect_btn": "探测", - "antigravity_args": "反重力程序启动参数", + "antigravity_ide_path_desc": "鎸囧畾 Antigravity IDE (浠g爜缂栬緫鍣? 鐨勫彲鎵ц鏂囦欢璺緞銆傝缃悗锛屽垏鎹㈣处鍙锋椂灏嗕弗鏍间繚鎶ゆ璺緞鐨勮繘绋嬩笉琚叧闂€?, + "antigravity_ide_path_select": "閫夋嫨 Antigravity IDE 鍙墽琛屾枃浠?, + "detect_btn": "鎺㈡祴", + "antigravity_args": "鍙嶉噸鍔涚▼搴忓惎鍔ㄥ弬鏁?, "antigravity_args_placeholder": "--user-data-dir=/path/to/data --some-other-flag", - "antigravity_args_desc": "为 Antigravity 程序指定启动参数,例如 --user-data-dir 用于指定用户数据目录", - "detect_args_btn": "检测", - "antigravity_args_detected": "启动参数已更新", - "antigravity_args_detect_error": "检测启动参数失败", - "accounts_page_size": "账号列表分页大小", - "page_size_auto": "自动计算 (推荐)", - "page_size_desc": "设置每页显示的账号数量。选择自动计算将根据窗口大小动态调整。", - "logs_title": "日志维护", - "logs_desc": "清理应用产生的日志缓存文件,不会影响账号数据。", - "clear_logs": "清理日志缓存", - "clear_logs_title": "清理日志确认", - "clear_logs_msg": "确定要清理所有日志缓存文件吗?", - "logs_cleared": "日志缓存已清理", - "antigravity_cache_title": "Antigravity 缓存清理", - "antigravity_cache_desc": "清理 Antigravity 应用的缓存可以解决登录失败、版本验证错误、OAuth 授权失败等问题。", - "antigravity_cache_warning": "请确保 Antigravity 应用已完全退出后再执行清理操作。", - "clear_antigravity_cache": "清理 Antigravity 缓存", - "clear_cache_confirm_title": "确认清理 Antigravity 缓存", - "clear_cache_confirm_msg": "将清理以下缓存目录:", - "cache_cleared_success": "缓存清理完成,释放 {{size}} MB 空间", - "cache_not_found": "未找到 Antigravity 缓存目录", - "debug_logs_title": "调试日志", - "debug_logs_enable_desc": "启用后会记录完整请求与响应链路,建议仅在排查问题时开启。", - "debug_logs_desc": "记录完整链路:原始输入、转换后的 v1internal 请求、以及上游响应。仅用于问题排查,可能包含敏感数据。", - "debug_log_dir": "调试日志输出目录", - "debug_log_dir_hint": "不填写则使用默认目录:{{path}}/debug_logs", - "debug_log_dir_select": "选择调试日志输出目录", - "http_api_title": "HTTP API 服务", - "http_api_desc": "为外部程序(如 VS Code 插件)提供本地 HTTP 接口。", - "http_api_enabled": "启用 HTTP API", - "http_api_enabled_desc": "启用后,外部程序可通过 HTTP 接口管理账号", - "http_api_port": "监听端口", - "http_api_port_desc": "修改端口后需要重启应用才能生效。如遇端口冲突,请更换为其他未被占用的端口。", - "http_api_port_placeholder": "默认端口 19527", - "http_api_port_invalid": "端口号无效(范围:1024-65535)", - "http_api_settings_saved": "HTTP API 设置已保存,重启应用后生效", - "http_api_restart_required": "⚠️ 需要重启应用后生效" + "antigravity_args_desc": "涓?Antigravity 绋嬪簭鎸囧畾鍚姩鍙傛暟锛屼緥濡?--user-data-dir 鐢ㄤ簬鎸囧畾鐢ㄦ埛鏁版嵁鐩綍", + "detect_args_btn": "妫€娴?, + "antigravity_args_detected": "鍚姩鍙傛暟宸叉洿鏂?, + "antigravity_args_detect_error": "妫€娴嬪惎鍔ㄥ弬鏁板け璐?, + "accounts_page_size": "璐﹀彿鍒楄〃鍒嗛〉澶у皬", + "page_size_auto": "鑷姩璁$畻 (鎺ㄨ崘)", + "page_size_desc": "璁剧疆姣忛〉鏄剧ず鐨勮处鍙锋暟閲忋€傞€夋嫨鑷姩璁$畻灏嗘牴鎹獥鍙eぇ灏忓姩鎬佽皟鏁淬€?, + "logs_title": "鏃ュ織缁存姢", + "logs_desc": "娓呯悊搴旂敤浜х敓鐨勬棩蹇楃紦瀛樻枃浠讹紝涓嶄細褰卞搷璐﹀彿鏁版嵁銆?, + "clear_logs": "娓呯悊鏃ュ織缂撳瓨", + "clear_logs_title": "娓呯悊鏃ュ織纭", + "clear_logs_msg": "纭畾瑕佹竻鐞嗘墍鏈夋棩蹇楃紦瀛樻枃浠跺悧锛?, + "logs_cleared": "鏃ュ織缂撳瓨宸叉竻鐞?, + "antigravity_cache_title": "Antigravity 缂撳瓨娓呯悊", + "antigravity_cache_desc": "娓呯悊 Antigravity 搴旂敤鐨勭紦瀛樺彲浠ヨВ鍐崇櫥褰曞け璐ャ€佺増鏈獙璇侀敊璇€丱Auth 鎺堟潈澶辫触绛夐棶棰樸€?, + "antigravity_cache_warning": "璇风‘淇?Antigravity 搴旂敤宸插畬鍏ㄩ€€鍑哄悗鍐嶆墽琛屾竻鐞嗘搷浣溿€?, + "clear_antigravity_cache": "娓呯悊 Antigravity 缂撳瓨", + "clear_cache_confirm_title": "纭娓呯悊 Antigravity 缂撳瓨", + "clear_cache_confirm_msg": "灏嗘竻鐞嗕互涓嬬紦瀛樼洰褰曪細", + "cache_cleared_success": "缂撳瓨娓呯悊瀹屾垚锛岄噴鏀?{{size}} MB 绌洪棿", + "cache_not_found": "鏈壘鍒?Antigravity 缂撳瓨鐩綍", + "debug_logs_title": "璋冭瘯鏃ュ織", + "debug_logs_enable_desc": "鍚敤鍚庝細璁板綍瀹屾暣璇锋眰涓庡搷搴旈摼璺紝寤鸿浠呭湪鎺掓煡闂鏃跺紑鍚€?, + "debug_logs_desc": "璁板綍瀹屾暣閾捐矾锛氬師濮嬭緭鍏ャ€佽浆鎹㈠悗鐨?v1internal 璇锋眰銆佷互鍙婁笂娓稿搷搴斻€備粎鐢ㄤ簬闂鎺掓煡锛屽彲鑳藉寘鍚晱鎰熸暟鎹€?, + "debug_log_dir": "璋冭瘯鏃ュ織杈撳嚭鐩綍", + "debug_log_dir_hint": "涓嶅~鍐欏垯浣跨敤榛樿鐩綍锛歿{path}}/debug_logs", + "debug_log_dir_select": "閫夋嫨璋冭瘯鏃ュ織杈撳嚭鐩綍", + "http_api_title": "HTTP API 鏈嶅姟", + "http_api_desc": "涓哄閮ㄧ▼搴忥紙濡?VS Code 鎻掍欢锛夋彁渚涙湰鍦?HTTP 鎺ュ彛銆?, + "http_api_enabled": "鍚敤 HTTP API", + "http_api_enabled_desc": "鍚敤鍚庯紝澶栭儴绋嬪簭鍙€氳繃 HTTP 鎺ュ彛绠$悊璐﹀彿", + "http_api_port": "鐩戝惉绔彛", + "http_api_port_desc": "淇敼绔彛鍚庨渶瑕侀噸鍚簲鐢ㄦ墠鑳界敓鏁堛€傚閬囩鍙e啿绐侊紝璇锋洿鎹负鍏朵粬鏈鍗犵敤鐨勭鍙c€?, + "http_api_port_placeholder": "榛樿绔彛 19527", + "http_api_port_invalid": "绔彛鍙锋棤鏁堬紙鑼冨洿锛?024-65535锛?, + "http_api_settings_saved": "HTTP API 璁剧疆宸蹭繚瀛橈紝閲嶅惎搴旂敤鍚庣敓鏁?, + "http_api_restart_required": "鈿狅笍 闇€瑕侀噸鍚簲鐢ㄥ悗鐢熸晥" }, "debug": { - "title": "调试控制台", - "desc": "实时查看应用日志,用于调试和问题排查", - "enabled": "已启用", - "disabled": "已禁用", - "disabled_hint": "调试控制台已关闭", - "disabled_desc": "开启后将实时记录应用日志", - "console_title": "调试控制台", - "console_desc": "查看实时应用日志,用于排查问题。", - "enable_desc": "开启后将捕获并显示后端日志。", - "open_btn": "打开控制台", - "debug_logging": "调试日志", - "debug_logging_desc": "启用后会记录完整请求与响应链路,建议仅在排查问题时开启。" + "title": "璋冭瘯鎺у埗鍙?, + "desc": "瀹炴椂鏌ョ湅搴旂敤鏃ュ織锛岀敤浜庤皟璇曞拰闂鎺掓煡", + "enabled": "宸插惎鐢?, + "disabled": "宸茬鐢?, + "disabled_hint": "璋冭瘯鎺у埗鍙板凡鍏抽棴", + "disabled_desc": "寮€鍚悗灏嗗疄鏃惰褰曞簲鐢ㄦ棩蹇?, + "console_title": "璋冭瘯鎺у埗鍙?, + "console_desc": "鏌ョ湅瀹炴椂搴旂敤鏃ュ織锛岀敤浜庢帓鏌ラ棶棰樸€?, + "enable_desc": "寮€鍚悗灏嗘崟鑾峰苟鏄剧ず鍚庣鏃ュ織銆?, + "open_btn": "鎵撳紑鎺у埗鍙?, + "debug_logging": "璋冭瘯鏃ュ織", + "debug_logging_desc": "鍚敤鍚庝細璁板綍瀹屾暣璇锋眰涓庡搷搴旈摼璺紝寤鸿浠呭湪鎺掓煡闂鏃跺紑鍚€? }, "menu": { - "title": "菜单显示设置", - "desc": "选择要在菜单栏中显示的功能项。隐藏不常用的菜单可以节省空间。", - "selected_items_note": "被选中的项目将显示在顶部菜单栏中。", - "required": "必选" + "title": "鑿滃崟鏄剧ず璁剧疆", + "desc": "閫夋嫨瑕佸湪鑿滃崟鏍忎腑鏄剧ず鐨勫姛鑳介」銆傞殣钘忎笉甯哥敤鐨勮彍鍗曞彲浠ヨ妭鐪佺┖闂淬€?, + "selected_items_note": "琚€変腑鐨勯」鐩皢鏄剧ず鍦ㄩ《閮ㄨ彍鍗曟爮涓€?, + "required": "蹇呴€? }, "about": { - "title": "关于", - "version": "应用版本", - "tech_stack": "技术栈", - "author": "作者", - "wechat": "微信公众号", - "telegram": "Telegram 频道", - "github": "开源地址", - "view_code": "查看代码", - "copyright": "Copyright © 2025-2026 Antigravity. All rights reserved.", - "check_update": "检测更新", - "checking_update": "检测中...", - "latest_version": "已是最新版本", - "new_version_available": "发现新版本 {{version}}", - "download_update": "前往下载", - "brew_upgrade": "通过 Homebrew 更新", - "brew_upgrading": "更新中...", - "brew_confirm_title": "通过 Homebrew 更新", - "brew_confirm_desc": "即将执行以下命令更新应用,更新完成后需要重启应用。", - "brew_quarantine_hint": "如更新后遇到「应用已损坏」提示,请在终端运行:", - "brew_confirm_btn": "开始更新", - "brew_success_title": "升级完成", - "brew_upgrade_success": "Homebrew 升级成功,请重启应用以加载新版本。", - "brew_restart_btn": "立即重启", - "brew_restart_failed": "自动重启失败,请手动关闭并重新打开应用", - "brew_upgrade_failed": "Homebrew 升级失败,请尝试在终端手动执行:brew upgrade --cask antigravity-tools", - "brew_error_brew_not_found": "未找到 Homebrew,请确认已安装 brew", - "brew_error_brew_exec_failed": "执行 brew 命令失败,请尝试在终端手动执行", - "brew_error_brew_timeout": "Homebrew 升级超时(3分钟),请在终端手动执行:brew upgrade --cask antigravity-tools", - "brew_error_brew_already_latest": "已是最新版本,无需升级", - "brew_error_brew_not_supported": "当前系统不支持 Homebrew 更新", - "update_check_failed": "检测更新失败", - "support_btn": "支持作者", - "support_title": "赞助支持", - "support_desc": "如果您觉得本工具对您有帮助,欢迎扫码请作者喝杯咖啡!您的支持是我持续维护项目的最大动力。", - "support_alipay": "支付宝", - "support_wechat": "微信支付", + "title": "鍏充簬", + "version": "搴旂敤鐗堟湰", + "tech_stack": "鎶€鏈爤", + "author": "浣滆€?, + "wechat": "寰俊鍏紬鍙?, + "telegram": "Telegram 棰戦亾", + "github": "寮€婧愬湴鍧€", + "view_code": "鏌ョ湅浠g爜", + "copyright": "Copyright 漏 2025-2026 Antigravity. All rights reserved.", + "check_update": "妫€娴嬫洿鏂?, + "checking_update": "妫€娴嬩腑...", + "latest_version": "宸叉槸鏈€鏂扮増鏈?, + "new_version_available": "鍙戠幇鏂扮増鏈?{{version}}", + "download_update": "鍓嶅線涓嬭浇", + "brew_upgrade": "閫氳繃 Homebrew 鏇存柊", + "brew_upgrading": "鏇存柊涓?..", + "brew_confirm_title": "閫氳繃 Homebrew 鏇存柊", + "brew_confirm_desc": "鍗冲皢鎵ц浠ヤ笅鍛戒护鏇存柊搴旂敤锛屾洿鏂板畬鎴愬悗闇€瑕侀噸鍚簲鐢ㄣ€?, + "brew_quarantine_hint": "濡傛洿鏂板悗閬囧埌銆屽簲鐢ㄥ凡鎹熷潖銆嶆彁绀猴紝璇峰湪缁堢杩愯锛?, + "brew_confirm_btn": "寮€濮嬫洿鏂?, + "brew_success_title": "鍗囩骇瀹屾垚", + "brew_upgrade_success": "Homebrew 鍗囩骇鎴愬姛锛岃閲嶅惎搴旂敤浠ュ姞杞芥柊鐗堟湰銆?, + "brew_restart_btn": "绔嬪嵆閲嶅惎", + "brew_restart_failed": "鑷姩閲嶅惎澶辫触锛岃鎵嬪姩鍏抽棴骞堕噸鏂版墦寮€搴旂敤", + "brew_upgrade_failed": "Homebrew 鍗囩骇澶辫触锛岃灏濊瘯鍦ㄧ粓绔墜鍔ㄦ墽琛岋細brew upgrade --cask antigravity-tools", + "brew_error_brew_not_found": "鏈壘鍒?Homebrew锛岃纭宸插畨瑁?brew", + "brew_error_brew_exec_failed": "鎵ц brew 鍛戒护澶辫触锛岃灏濊瘯鍦ㄧ粓绔墜鍔ㄦ墽琛?, + "brew_error_brew_timeout": "Homebrew 鍗囩骇瓒呮椂锛?鍒嗛挓锛夛紝璇峰湪缁堢鎵嬪姩鎵ц锛歜rew upgrade --cask antigravity-tools", + "brew_error_brew_already_latest": "宸叉槸鏈€鏂扮増鏈紝鏃犻渶鍗囩骇", + "brew_error_brew_not_supported": "褰撳墠绯荤粺涓嶆敮鎸?Homebrew 鏇存柊", + "update_check_failed": "妫€娴嬫洿鏂板け璐?, + "support_btn": "鏀寔浣滆€?, + "support_title": "璧炲姪鏀寔", + "support_desc": "濡傛灉鎮ㄨ寰楁湰宸ュ叿瀵规偍鏈夊府鍔╋紝娆㈣繋鎵爜璇蜂綔鑰呭枬鏉挅鍟★紒鎮ㄧ殑鏀寔鏄垜鎸佺画缁存姢椤圭洰鐨勬渶澶у姩鍔涖€?, + "support_alipay": "鏀粯瀹?, + "support_wechat": "寰俊鏀粯", "support_buymeacoffee": "Buy Me a Coffee" }, "advanced_thinking": { - "title": "高级思维与全局配置", - "description": "集中管理思考能力、图像模式及全局指令。" + "title": "楂樼骇鎬濈淮涓庡叏灞€閰嶇疆", + "description": "闆嗕腑绠$悊鎬濊€冭兘鍔涖€佸浘鍍忔ā寮忓強鍏ㄥ眬鎸囦护銆? }, "thinking_budget": { - "title": "思考预算 (Thinking Budget)", - "description": "控制 AI 深度思考时的 Token 预算。某些模型(如 Flash、带 -thinking 后缀的模型)受上游 24576 上限限制。", - "mode_label": "处理模式", + "title": "鎬濊€冮绠?(Thinking Budget)", + "description": "鎺у埗 AI 娣卞害鎬濊€冩椂鐨?Token 棰勭畻銆傛煇浜涙ā鍨嬶紙濡?Flash銆佸甫 -thinking 鍚庣紑鐨勬ā鍨嬶級鍙椾笂娓?24576 涓婇檺闄愬埗銆?, + "mode_label": "澶勭悊妯″紡", "mode": { - "auto": "自动限制", - "passthrough": "透传", - "custom": "自定义", - "adaptive": "自适应" + "auto": "鑷姩闄愬埗", + "passthrough": "閫忎紶", + "custom": "鑷畾涔?, + "adaptive": "鑷€傚簲" }, - "effort_label": "思考强度", + "effort_label": "鎬濊€冨己搴?, "effort": { - "low": "低 (Low)", - "medium": "中 (Medium)", - "high": "高 (High)" + "low": "浣?(Low)", + "medium": "涓?(Medium)", + "high": "楂?(High)" }, - "auto_hint": "自动模式:对 Flash 模型、-thinking 后缀模型、以及启用 Web Search 的请求自动限制在 24576 以避免 API 错误。", - "passthrough_warning": "透传:直接使用调用方原始值,不支持高值可能导致失败。", - "custom_value_hint": "推荐:24576 (Flash) 或 51200 (扩展)", - "adaptive_hint": "自适应模式:由模型根据任务复杂度自动调整思考量。Claude 4.6+ 推荐使用此模式。", + "auto_hint": "鑷姩妯″紡锛氬 Flash 妯″瀷銆?thinking 鍚庣紑妯″瀷銆佷互鍙婂惎鐢?Web Search 鐨勮姹傝嚜鍔ㄩ檺鍒跺湪 24576 浠ラ伩鍏?API 閿欒銆?, + "passthrough_warning": "閫忎紶锛氱洿鎺ヤ娇鐢ㄨ皟鐢ㄦ柟鍘熷鍊硷紝涓嶆敮鎸侀珮鍊煎彲鑳藉鑷村け璐ャ€?, + "custom_value_hint": "鎺ㄨ崘锛?4576 (Flash) 鎴?51200 (鎵╁睍)", + "adaptive_hint": "鑷€傚簲妯″紡锛氱敱妯″瀷鏍规嵁浠诲姟澶嶆潅搴﹁嚜鍔ㄨ皟鏁存€濊€冮噺銆侰laude 4.6+ 鎺ㄨ崘浣跨敤姝ゆā寮忋€?, "tokens": "tokens" }, "image_thinking_mode": { - "title": "图像思维模式 (Image Thinking Mode)", - "hint": "影响画质与生成流程", + "title": "鍥惧儚鎬濈淮妯″紡 (Image Thinking Mode)", + "hint": "褰卞搷鐢昏川涓庣敓鎴愭祦绋?, "options": { - "enabled": "开启", - "disabled": "关闭", - "enabled_desc": "开启:保留思维链,返回草图 + 成品双图。", - "disabled_desc": "关闭:禁用思维链,直接生成单张超清图片(画质优先)。" + "enabled": "寮€鍚?, + "disabled": "鍏抽棴", + "enabled_desc": "寮€鍚細淇濈暀鎬濈淮閾撅紝杩斿洖鑽夊浘 + 鎴愬搧鍙屽浘銆?, + "disabled_desc": "鍏抽棴锛氱鐢ㄦ€濈淮閾撅紝鐩存帴鐢熸垚鍗曞紶瓒呮竻鍥剧墖锛堢敾璐ㄤ紭鍏堬級銆? } }, "global_system_prompt": { - "title": "全局系统提示词 (Global System Prompt)", - "hint": "自动注入所有请求的 systemInstruction", - "placeholder": "输入全局系统提示词...\n例如:你是一位资深的全栈开发工程师,擅长 React 和 Rust。请使用简体中文回复。", - "char_count": "{{count}} 字符", - "long_prompt_warning": "提示词较长(超过 2000 字符),可能会占用较多的上下文窗口空间。" + "title": "鍏ㄥ眬绯荤粺鎻愮ず璇?(Global System Prompt)", + "hint": "鑷姩娉ㄥ叆鎵€鏈夎姹傜殑 systemInstruction", + "placeholder": "杈撳叆鍏ㄥ眬绯荤粺鎻愮ず璇?..\n渚嬪锛氫綘鏄竴浣嶈祫娣辩殑鍏ㄦ爤寮€鍙戝伐绋嬪笀锛屾搮闀?React 鍜?Rust銆傝浣跨敤绠€浣撲腑鏂囧洖澶嶃€?, + "char_count": "{{count}} 瀛楃", + "long_prompt_warning": "鎻愮ず璇嶈緝闀匡紙瓒呰繃 2000 瀛楃锛夛紝鍙兘浼氬崰鐢ㄨ緝澶氱殑涓婁笅鏂囩獥鍙g┖闂淬€? } }, "tray": { - "current": "当前", - "quota": "额度", - "switch_next": "切换下一个账号", - "refresh_current": "刷新当前账号额度", - "show_window": "显示主窗口", - "quit": "退出应用 (Exit)", - "no_account": "无账号", - "unknown_quota": "未知 (点击刷新)", - "forbidden": "账号被封禁" + "current": "褰撳墠", + "quota": "棰濆害", + "switch_next": "鍒囨崲涓嬩竴涓处鍙?, + "refresh_current": "鍒锋柊褰撳墠璐﹀彿棰濆害", + "show_window": "鏄剧ず涓荤獥鍙?, + "quit": "閫€鍑哄簲鐢?(Exit)", + "no_account": "鏃犺处鍙?, + "unknown_quota": "鏈煡 (鐐瑰嚮鍒锋柊)", + "forbidden": "璐﹀彿琚皝绂? }, "proxy": { - "title": "API 反代服务", + "title": "API 鍙嶄唬鏈嶅姟", "status": { - "running": "服务运行中", - "stopped": "服务已停止", - "accounts_available": "{{count}} 个账号可用", - "processing": "处理中..." + "running": "鏈嶅姟杩愯涓?, + "stopped": "鏈嶅姟宸插仠姝?, + "accounts_available": "{{count}} 涓处鍙峰彲鐢?, + "processing": "澶勭悊涓?.." }, "action": { - "start": "启动服务", - "stop": "停止服务" + "start": "鍚姩鏈嶅姟", + "stop": "鍋滄鏈嶅姟" }, "config": { - "title": "服务配置", + "title": "鏈嶅姟閰嶇疆", "request": { - "user_agent": "User-Agent 覆盖", - "user_agent_tooltip": "自定义发送给上游 API 的 User-Agent 请求头。留空则使用默认值。", - "user_agent_hint": "当前默认值: antigravity/ /", - "user_agent_placeholder": "输入自定义 User-Agent 字符串..." + "user_agent": "User-Agent 瑕嗙洊", + "user_agent_tooltip": "鑷畾涔夊彂閫佺粰涓婃父 API 鐨?User-Agent 璇锋眰澶淬€傜暀绌哄垯浣跨敤榛樿鍊笺€?, + "user_agent_hint": "褰撳墠榛樿鍊? antigravity/ /", + "user_agent_placeholder": "杈撳叆鑷畾涔?User-Agent 瀛楃涓?.." }, - "port": "监听端口", - "port_tooltip": "本地 API 代理监听的端口。需要先停止服务再修改,修改后需重启生效。", - "port_hint": "默认 8045,修改端口需重启服务", - "auto_start": "跟随应用自动启动", - "auto_start_tooltip": "应用启动时自动启动本地 API 代理服务。", - "allow_lan_access": "允许局域网访问", - "allow_lan_access_tooltip": "开启后绑定到 0.0.0.0,局域网其他设备也能访问。建议同时开启鉴权并妥善保管 API 密钥;修改后需重启生效。", - "allow_lan_access_hint_enabled": "🌐 监听 0.0.0.0,局域网设备可访问", - "allow_lan_access_hint_disabled": "🔒 仅监听 127.0.0.1,仅本机可访问(隐私优先)", - "allow_lan_access_warning": "⚠️ 开启后局域网内其他设备可访问,请确保 API 密钥安全", - "allow_lan_access_restart_hint": "ℹ️ 需要重启服务后生效", - "api_key": "API 密钥", - "api_key_tooltip": "启用鉴权后,客户端访问代理所需的共享密钥。重新生成会立即使旧密钥失效。", - "btn_regenerate": "重新生成密钥", - "btn_edit": "编辑", - "btn_save": "保存", - "btn_copy": "复制", - "btn_copied": "已复制", - "warning_key": "注意:请妥善保管您的 API 密钥,不要泄露给他人。", - "api_key_invalid": "API 密钥格式无效,必须以 sk- 开头且长度至少 10 个字符", - "api_key_updated": "API 密钥已更新", - "admin_password": "Web UI 管理后台密码", - "admin_password_tooltip": "用于登录 Web 管理后台的密码。如果为空,则默认使用 API 密钥(API Key)。", - "admin_password_default": "(同 API 密钥)", - "admin_password_placeholder": "输入新密码,留空则使用 API 密钥", - "admin_password_hint": "提示:在 Docker/Web 部署场景中,您可以设置一个独立的登录密码,提高 API 密钥的安全性。", - "admin_password_short": "密码太短(最少 4 个字符)", - "admin_password_updated": "Web UI 登录密码已更新", + "port": "鐩戝惉绔彛", + "port_tooltip": "鏈湴 API 浠g悊鐩戝惉鐨勭鍙c€傞渶瑕佸厛鍋滄鏈嶅姟鍐嶄慨鏀癸紝淇敼鍚庨渶閲嶅惎鐢熸晥銆?, + "port_hint": "榛樿 8045锛屼慨鏀圭鍙i渶閲嶅惎鏈嶅姟", + "auto_start": "璺熼殢搴旂敤鑷姩鍚姩", + "auto_start_tooltip": "搴旂敤鍚姩鏃惰嚜鍔ㄥ惎鍔ㄦ湰鍦?API 浠g悊鏈嶅姟銆?, + "allow_lan_access": "鍏佽灞€鍩熺綉璁块棶", + "allow_lan_access_tooltip": "寮€鍚悗缁戝畾鍒?0.0.0.0锛屽眬鍩熺綉鍏朵粬璁惧涔熻兘璁块棶銆傚缓璁悓鏃跺紑鍚壌鏉冨苟濡ュ杽淇濈 API 瀵嗛挜锛涗慨鏀瑰悗闇€閲嶅惎鐢熸晥銆?, + "allow_lan_access_hint_enabled": "馃寪 鐩戝惉 0.0.0.0锛屽眬鍩熺綉璁惧鍙闂?, + "allow_lan_access_hint_disabled": "馃敀 浠呯洃鍚?127.0.0.1锛屼粎鏈満鍙闂紙闅愮浼樺厛锛?, + "allow_lan_access_warning": "鈿狅笍 寮€鍚悗灞€鍩熺綉鍐呭叾浠栬澶囧彲璁块棶锛岃纭繚 API 瀵嗛挜瀹夊叏", + "allow_lan_access_restart_hint": "鈩癸笍 闇€瑕侀噸鍚湇鍔″悗鐢熸晥", + "api_key": "API 瀵嗛挜", + "api_key_tooltip": "鍚敤閴存潈鍚庯紝瀹㈡埛绔闂唬鐞嗘墍闇€鐨勫叡浜瘑閽ャ€傞噸鏂扮敓鎴愪細绔嬪嵆浣挎棫瀵嗛挜澶辨晥銆?, + "btn_regenerate": "閲嶆柊鐢熸垚瀵嗛挜", + "btn_edit": "缂栬緫", + "btn_save": "淇濆瓨", + "btn_copy": "澶嶅埗", + "btn_copied": "宸插鍒?, + "warning_key": "娉ㄦ剰锛氳濡ュ杽淇濈鎮ㄧ殑 API 瀵嗛挜锛屼笉瑕佹硠闇茬粰浠栦汉銆?, + "api_key_invalid": "API 瀵嗛挜鏍煎紡鏃犳晥,蹇呴』浠?sk- 寮€澶翠笖闀垮害鑷冲皯 10 涓瓧绗?, + "api_key_updated": "API 瀵嗛挜宸叉洿鏂?, + "admin_password": "Web UI 绠$悊鍚庡彴瀵嗙爜", + "admin_password_tooltip": "鐢ㄤ簬鐧诲綍 Web 绠$悊鍚庡彴鐨勫瘑鐮併€傚鏋滀负绌猴紝鍒欓粯璁や娇鐢?API 瀵嗛挜锛圓PI Key锛夈€?, + "admin_password_default": "锛堝悓 API 瀵嗛挜锛?, + "admin_password_placeholder": "杈撳叆鏂板瘑鐮侊紝鐣欑┖鍒欎娇鐢?API 瀵嗛挜", + "admin_password_hint": "鎻愮ず锛氬湪 Docker/Web 閮ㄧ讲鍦烘櫙涓紝鎮ㄥ彲浠ヨ缃竴涓嫭绔嬬殑鐧诲綍瀵嗙爜锛屾彁楂?API 瀵嗛挜鐨勫畨鍏ㄦ€с€?, + "admin_password_short": "瀵嗙爜澶煭锛堟渶灏?4 涓瓧绗︼級", + "admin_password_updated": "Web UI 鐧诲綍瀵嗙爜宸叉洿鏂?, "auth": { - "title": "访问授权", - "title_tooltip": "控制代理是否需要鉴权,以及哪些路由需要提供 API 密钥。", - "enabled": "已启用", - "enabled_tooltip": "快速开关鉴权(通过切换鉴权模式实现)。开启后客户端需在请求头提供 Authorization: Bearer 或 x-api-key。", - "mode": "模式", - "mode_tooltip": "选择鉴权覆盖范围:关闭=不鉴权;全局=所有接口都需密钥;除健康检查外=/healthz 不鉴权;自动=本机模式默认关闭,局域网模式默认“除健康检查外”。", - "hint": "开启后客户端需通过 Authorization: Bearer ... 传入 API 密钥(如选择“除健康检查外”则 /healthz 免鉴权)。", + "title": "璁块棶鎺堟潈", + "title_tooltip": "鎺у埗浠g悊鏄惁闇€瑕侀壌鏉冿紝浠ュ強鍝簺璺敱闇€瑕佹彁渚?API 瀵嗛挜銆?, + "enabled": "宸插惎鐢?, + "enabled_tooltip": "蹇€熷紑鍏抽壌鏉冿紙閫氳繃鍒囨崲閴存潈妯″紡瀹炵幇锛夈€傚紑鍚悗瀹㈡埛绔渶鍦ㄨ姹傚ご鎻愪緵 Authorization: Bearer 鎴?x-api-key銆?, + "mode": "妯″紡", + "mode_tooltip": "閫夋嫨閴存潈瑕嗙洊鑼冨洿锛氬叧闂?涓嶉壌鏉冿紱鍏ㄥ眬=鎵€鏈夋帴鍙i兘闇€瀵嗛挜锛涢櫎鍋ュ悍妫€鏌ュ=/healthz 涓嶉壌鏉冿紱鑷姩=鏈満妯″紡榛樿鍏抽棴锛屽眬鍩熺綉妯″紡榛樿鈥滈櫎鍋ュ悍妫€鏌ュ鈥濄€?, + "hint": "寮€鍚悗瀹㈡埛绔渶閫氳繃 Authorization: Bearer ... 浼犲叆 API 瀵嗛挜锛堝閫夋嫨鈥滈櫎鍋ュ悍妫€鏌ュ鈥濆垯 /healthz 鍏嶉壌鏉冿級銆?, "modes": { - "off": "关闭(开放)", - "strict": "全局(严格)", - "all_except_health": "全局(除健康检查外)", - "auto": "自动(推荐)" + "off": "鍏抽棴锛堝紑鏀撅級", + "strict": "鍏ㄥ眬锛堜弗鏍硷級", + "all_except_health": "鍏ㄥ眬锛堥櫎鍋ュ悍妫€鏌ュ锛?, + "auto": "鑷姩锛堟帹鑽愶級" } }, "zai": { - "title": "z.ai(GLM)提供商", - "title_tooltip": "为 Claude 协议提供可选的 Anthropic 兼容上游(z.ai)。只影响 Claude 协议请求,Google 账号池仍按原逻辑工作。", - "subtitle": "可选的 Anthropic 兼容上游,仅用于 Claude 协议请求。", - "enabled": "已启用", - "enabled_tooltip": "启用后,Claude 协议请求将按“分发模式”路由到 z.ai。", + "title": "z.ai锛圙LM锛夋彁渚涘晢", + "title_tooltip": "涓?Claude 鍗忚鎻愪緵鍙€夌殑 Anthropic 鍏煎涓婃父锛坺.ai锛夈€傚彧褰卞搷 Claude 鍗忚璇锋眰锛孏oogle 璐﹀彿姹犱粛鎸夊師閫昏緫宸ヤ綔銆?, + "subtitle": "鍙€夌殑 Anthropic 鍏煎涓婃父锛屼粎鐢ㄤ簬 Claude 鍗忚璇锋眰銆?, + "enabled": "宸插惎鐢?, + "enabled_tooltip": "鍚敤鍚庯紝Claude 鍗忚璇锋眰灏嗘寜鈥滃垎鍙戞ā寮忊€濊矾鐢卞埌 z.ai銆?, "base_url": "Base URL", - "base_url_tooltip": "z.ai Anthropic 兼容接口的基础地址。默认 https://api.z.ai/api/anthropic,代理会在其后拼接 /v1/messages 等路径。", - "dispatch_mode": "分发模式", - "dispatch_mode_tooltip": "控制何时使用 z.ai:关闭=不使用;全部 Claude 请求=所有 /v1/messages 等都转发到 z.ai;加入队列=把 z.ai 当作队列中的 1 个槽位按轮询分配;仅兜底=仅当没有可用 Google 账号时才使用。", + "base_url_tooltip": "z.ai Anthropic 鍏煎鎺ュ彛鐨勫熀纭€鍦板潃銆傞粯璁?https://api.z.ai/api/anthropic锛屼唬鐞嗕細鍦ㄥ叾鍚庢嫾鎺?/v1/messages 绛夎矾寰勩€?, + "dispatch_mode": "鍒嗗彂妯″紡", + "dispatch_mode_tooltip": "鎺у埗浣曟椂浣跨敤 z.ai锛氬叧闂?涓嶄娇鐢紱鍏ㄩ儴 Claude 璇锋眰=鎵€鏈?/v1/messages 绛夐兘杞彂鍒?z.ai锛涘姞鍏ラ槦鍒?鎶?z.ai 褰撲綔闃熷垪涓殑 1 涓Ы浣嶆寜杞鍒嗛厤锛涗粎鍏滃簳=浠呭綋娌℃湁鍙敤 Google 璐﹀彿鏃舵墠浣跨敤銆?, "api_key": "API Key", - "api_key_tooltip": "用于调用 z.ai 上游的 API Key(本地存储)。启用 z.ai 或 MCP 功能前必须配置。", - "api_key_placeholder": "在此粘贴 z.ai API Key", - "warning": "提示:该 Key 将保存在本机应用数据目录中。", + "api_key_tooltip": "鐢ㄤ簬璋冪敤 z.ai 涓婃父鐨?API Key锛堟湰鍦板瓨鍌級銆傚惎鐢?z.ai 鎴?MCP 鍔熻兘鍓嶅繀椤婚厤缃€?, + "api_key_placeholder": "鍦ㄦ绮樿创 z.ai API Key", + "warning": "鎻愮ず锛氳 Key 灏嗕繚瀛樺湪鏈満搴旂敤鏁版嵁鐩綍涓€?, "models": { - "title": "模型映射", - "title_tooltip": "从 z.ai 拉取可用模型 ID,并配置如何把 Claude/Anthropic 的 model 名称转换为 z.ai 的模型 ID。", - "refresh": "拉取模型", - "refreshing": "拉取中...", - "hint": "可用模型:{{count}}。可从建议中选择,或手动输入自定义模型 ID。", - "error": "拉取模型失败:{{error}}", - "select_placeholder": "选择模型...", - "opus": "Opus 家族 → z.ai 模型", - "opus_tooltip": "当请求的 model 包含“opus”(如 claude-opus-*)时默认使用的 z.ai 模型 ID。", - "sonnet": "Sonnet 家族 → z.ai 模型", - "sonnet_tooltip": "其他 Claude 模型(如 claude-sonnet-* 以及大多数 claude-*)默认使用的 z.ai 模型 ID。", - "haiku": "Haiku 家族 → z.ai 模型", - "haiku_tooltip": "当请求的 model 包含“haiku”(如 claude-haiku-*)时默认使用的 z.ai 模型 ID。", - "advanced_title": "高级覆盖规则", - "advanced_tooltip": "可选的精确匹配覆盖规则:如果 incoming model 字符串与规则键完全一致,则替换为对应的 z.ai 模型 ID。", + "title": "妯″瀷鏄犲皠", + "title_tooltip": "浠?z.ai 鎷夊彇鍙敤妯″瀷 ID锛屽苟閰嶇疆濡備綍鎶?Claude/Anthropic 鐨?model 鍚嶇О杞崲涓?z.ai 鐨勬ā鍨?ID銆?, + "refresh": "鎷夊彇妯″瀷", + "refreshing": "鎷夊彇涓?..", + "hint": "鍙敤妯″瀷锛歿{count}}銆傚彲浠庡缓璁腑閫夋嫨锛屾垨鎵嬪姩杈撳叆鑷畾涔夋ā鍨?ID銆?, + "error": "鎷夊彇妯″瀷澶辫触锛歿{error}}", + "select_placeholder": "閫夋嫨妯″瀷...", + "opus": "Opus 瀹舵棌 鈫?z.ai 妯″瀷", + "opus_tooltip": "褰撹姹傜殑 model 鍖呭惈鈥渙pus鈥濓紙濡?claude-opus-*锛夋椂榛樿浣跨敤鐨?z.ai 妯″瀷 ID銆?, + "sonnet": "Sonnet 瀹舵棌 鈫?z.ai 妯″瀷", + "sonnet_tooltip": "鍏朵粬 Claude 妯″瀷锛堝 claude-sonnet-* 浠ュ強澶у鏁?claude-*锛夐粯璁や娇鐢ㄧ殑 z.ai 妯″瀷 ID銆?, + "haiku": "Haiku 瀹舵棌 鈫?z.ai 妯″瀷", + "haiku_tooltip": "褰撹姹傜殑 model 鍖呭惈鈥渉aiku鈥濓紙濡?claude-haiku-*锛夋椂榛樿浣跨敤鐨?z.ai 妯″瀷 ID銆?, + "advanced_title": "楂樼骇瑕嗙洊瑙勫垯", + "advanced_tooltip": "鍙€夌殑绮剧‘鍖归厤瑕嗙洊瑙勫垯锛氬鏋?incoming model 瀛楃涓蹭笌瑙勫垯閿畬鍏ㄤ竴鑷达紝鍒欐浛鎹负瀵瑰簲鐨?z.ai 妯″瀷 ID銆?, "from_label": "incoming model", - "to_label": "z.ai 模型", - "add_rule": "添加", - "empty": "尚未配置自定义替换规则。", - "from_placeholder": "源模型 (如 claude-3-opus)", - "to_placeholder": "映射至 (如 glm-4)" + "to_label": "z.ai 妯″瀷", + "add_rule": "娣诲姞", + "empty": "灏氭湭閰嶇疆鑷畾涔夋浛鎹㈣鍒欍€?, + "from_placeholder": "婧愭ā鍨?(濡?claude-3-opus)", + "to_placeholder": "鏄犲皠鑷?(濡?glm-4)" }, "modes": { - "off": "关闭", - "exclusive": "全部 Claude 请求走 z.ai", - "pooled": "加入队列(占 1 个槽位)", - "fallback": "仅兜底" + "off": "鍏抽棴", + "exclusive": "鍏ㄩ儴 Claude 璇锋眰璧?z.ai", + "pooled": "鍔犲叆闃熷垪锛堝崰 1 涓Ы浣嶏級", + "fallback": "浠呭厹搴? }, "mcp": { - "title": "MCP 服务(通过本地代理)", - "title_tooltip": "在本地代理上暴露可选的 /mcp/* 端点,供 MCP 客户端直连。仅在服务运行、z.ai 配置完成且对应开关开启时可用。", - "enabled": "启用 MCP 反代", - "enabled_tooltip": "MCP 端点总开关;关闭时所有 /mcp/* 路由将返回 404。", - "web_search": "网页搜索", - "web_search_tooltip": "启用后开放 /mcp/web_search_prime/mcp,并转发到 z.ai 的 Web Search MCP 上游。", - "web_reader": "网页阅读", - "web_reader_tooltip": "启用后开放 /mcp/web_reader/mcp,并转发到 z.ai 的 Web Reader MCP 上游。", - "vision": "视觉", - "vision_tooltip": "启用后开放 /mcp/zai-mcp-server/mcp(本地 MCP 服务),提供视觉相关工具能力,并通过 z.ai 执行。", - "local_endpoints": "本地地址(在 MCP 客户端中配置以下 URL):", - "local_endpoints_tooltip": "把这些 URL 填到你的 MCP 客户端里即可。它们使用同一个代理端口,并遵循当前的鉴权策略。" + "title": "MCP 鏈嶅姟锛堥€氳繃鏈湴浠g悊锛?, + "title_tooltip": "鍦ㄦ湰鍦颁唬鐞嗕笂鏆撮湶鍙€夌殑 /mcp/* 绔偣锛屼緵 MCP 瀹㈡埛绔洿杩炪€備粎鍦ㄦ湇鍔¤繍琛屻€亃.ai 閰嶇疆瀹屾垚涓斿搴斿紑鍏冲紑鍚椂鍙敤銆?, + "enabled": "鍚敤 MCP 鍙嶄唬", + "enabled_tooltip": "MCP 绔偣鎬诲紑鍏筹紱鍏抽棴鏃舵墍鏈?/mcp/* 璺敱灏嗚繑鍥?404銆?, + "web_search": "缃戦〉鎼滅储", + "web_search_tooltip": "鍚敤鍚庡紑鏀?/mcp/web_search_prime/mcp锛屽苟杞彂鍒?z.ai 鐨?Web Search MCP 涓婃父銆?, + "web_reader": "缃戦〉闃呰", + "web_reader_tooltip": "鍚敤鍚庡紑鏀?/mcp/web_reader/mcp锛屽苟杞彂鍒?z.ai 鐨?Web Reader MCP 涓婃父銆?, + "vision": "瑙嗚", + "vision_tooltip": "鍚敤鍚庡紑鏀?/mcp/zai-mcp-server/mcp锛堟湰鍦?MCP 鏈嶅姟锛夛紝鎻愪緵瑙嗚鐩稿叧宸ュ叿鑳藉姏锛屽苟閫氳繃 z.ai 鎵ц銆?, + "local_endpoints": "鏈湴鍦板潃锛堝湪 MCP 瀹㈡埛绔腑閰嶇疆浠ヤ笅 URL锛夛細", + "local_endpoints_tooltip": "鎶婅繖浜?URL 濉埌浣犵殑 MCP 瀹㈡埛绔噷鍗冲彲銆傚畠浠娇鐢ㄥ悓涓€涓唬鐞嗙鍙o紝骞堕伒寰綋鍓嶇殑閴存潈绛栫暐銆? } }, - "request_timeout": "请求超时", - "request_timeout_tooltip": "代理等待上游响应的最大时间(秒),包含流式输出。长文本/长推理可适当调大;修改后需重启生效。", - "request_timeout_hint": "默认 120 秒,范围 30-7200 秒。修改后需重启服务生效。", - "enable_logging": "启用请求日志", - "enable_logging_hint": "记录历史记录以便调试 (微小性能损耗)", + "request_timeout": "璇锋眰瓒呮椂", + "request_timeout_tooltip": "浠g悊绛夊緟涓婃父鍝嶅簲鐨勬渶澶ф椂闂达紙绉掞級锛屽寘鍚祦寮忚緭鍑恒€傞暱鏂囨湰/闀挎帹鐞嗗彲閫傚綋璋冨ぇ锛涗慨鏀瑰悗闇€閲嶅惎鐢熸晥銆?, + "request_timeout_hint": "榛樿 120 绉掞紝鑼冨洿 30-7200 绉掋€備慨鏀瑰悗闇€閲嶅惎鏈嶅姟鐢熸晥銆?, + "enable_logging": "鍚敤璇锋眰鏃ュ織", + "enable_logging_hint": "璁板綍鍘嗗彶璁板綍浠ヤ究璋冭瘯 (寰皬鎬ц兘鎹熻€?", "upstream_proxy": { - "title": "全局上游代理 (Global Proxy)", - "desc": "开启后,应用内所有外部请求(API 反代、Token 刷新、配额查询、更新检测)都将通过此代理。", - "desc_short": "用于无法匹配代理池账号时的通用出口或降级方案。", - "enable": "启用上游代理", - "url": "代理地址", - "url_placeholder": "例如: http://127.0.0.1:7890 或 socks5://127.0.0.1:7890", - "tip": "支持 HTTP、HTTPS 和 SOCKS5 协议。", - "socks5h_hint": "若需避开上游风控并保留原始域名解析 (Remote DNS),请手动将协议改为 socks5h://", - "validation_error": "启用上游代理时必须填写代理地址", - "restart_hint": "代理配置已保存,重启应用后生效" + "title": "鍏ㄥ眬涓婃父浠g悊 (Global Proxy)", + "desc": "寮€鍚悗锛屽簲鐢ㄥ唴鎵€鏈夊閮ㄨ姹傦紙API 鍙嶄唬銆乀oken 鍒锋柊銆侀厤棰濇煡璇€佹洿鏂版娴嬶級閮藉皢閫氳繃姝や唬鐞嗐€?, + "desc_short": "鐢ㄤ簬鏃犳硶鍖归厤浠g悊姹犺处鍙锋椂鐨勯€氱敤鍑哄彛鎴栭檷绾ф柟妗堛€?, + "enable": "鍚敤涓婃父浠g悊", + "url": "浠g悊鍦板潃", + "url_placeholder": "渚嬪: http://127.0.0.1:7890 鎴?socks5://127.0.0.1:7890", + "tip": "鏀寔 HTTP銆丠TTPS 鍜?SOCKS5 鍗忚銆?, + "socks5h_hint": "鑻ラ渶閬垮紑涓婃父椋庢帶骞朵繚鐣欏師濮嬪煙鍚嶈В鏋?(Remote DNS)锛岃鎵嬪姩灏嗗崗璁敼涓?socks5h://", + "validation_error": "鍚敤涓婃父浠g悊鏃跺繀椤诲~鍐欎唬鐞嗗湴鍧€", + "restart_hint": "浠g悊閰嶇疆宸蹭繚瀛橈紝閲嶅惎搴旂敤鍚庣敓鏁? }, "scheduling": { - "title": "账号轮换与会话调度", - "title_tooltip": "控制会话如何绑定到账号,以及触发限流时的行为。", - "subtitle": "针对全协议客户端优化 Prompt Caching 和限流处理 (OpenAI/Gemini/Claude)。", - "mode": "调度模式", - "mode_tooltip": "缓存优先:绑定账号,限流时强制等待(最大化缓存);平衡:绑定账号,限流时自动热切;性能优先:不绑定,全自动轮换。", + "title": "璐﹀彿杞崲涓庝細璇濊皟搴?, + "title_tooltip": "鎺у埗浼氳瘽濡備綍缁戝畾鍒拌处鍙凤紝浠ュ強瑙﹀彂闄愭祦鏃剁殑琛屼负銆?, + "subtitle": "閽堝鍏ㄥ崗璁鎴风浼樺寲 Prompt Caching 鍜岄檺娴佸鐞?(OpenAI/Gemini/Claude)銆?, + "mode": "璋冨害妯″紡", + "mode_tooltip": "缂撳瓨浼樺厛锛氱粦瀹氳处鍙凤紝闄愭祦鏃跺己鍒剁瓑寰咃紙鏈€澶у寲缂撳瓨锛夛紱骞宠 锛氱粦瀹氳处鍙凤紝闄愭祦鏃惰嚜鍔ㄧ儹鍒囷紱鎬ц兘浼樺厛锛氫笉缁戝畾锛屽叏鑷姩杞崲銆?, "modes": { - "CacheFirst": "缓存优先 (Cache First)", - "Balance": "平衡轮换 (Balance)", - "PerformanceFirst": "性能优先 (Performance)" + "CacheFirst": "缂撳瓨浼樺厛 (Cache First)", + "Balance": "骞宠 杞崲 (Balance)", + "PerformanceFirst": "鎬ц兘浼樺厛 (Performance)" }, "modes_desc": { - "CacheFirst": "绑定会话与账号,限流时精准等待(最大化 Prompt Cache 命中率)。", - "Balance": "绑定会话,限流时自动热切换至可用账号(兼顾缓存与可用性)。", - "PerformanceFirst": "无会话绑定,纯随机轮换(适合高并发,不考虑缓存)。" + "CacheFirst": "缁戝畾浼氳瘽涓庤处鍙凤紝闄愭祦鏃剁簿鍑嗙瓑寰咃紙鏈€澶у寲 Prompt Cache 鍛戒腑鐜囷級銆?, + "Balance": "缁戝畾浼氳瘽锛岄檺娴佹椂鑷姩鐑垏鎹㈣嚦鍙敤璐﹀彿锛堝吋椤剧紦瀛樹笌鍙敤鎬э級銆?, + "PerformanceFirst": "鏃犱細璇濈粦瀹氾紝绾殢鏈鸿疆鎹紙閫傚悎楂樺苟鍙戯紝涓嶈€冭檻缂撳瓨锛夈€? }, - "max_wait": "最大等待时长 (秒)", - "max_wait_tooltip": "仅在“缓存优先”模式下生效:如果账号限流重置时间小于此值,则原地等待而非切换账号。", - "clear_bindings": "清除会话绑定", - "clear_bindings_tooltip": "立即断开所有会话与账号的绑定关系,强制下一次请求重新分配账号。", - "clear_rate_limits": "清除限流记录", - "clear_rate_limits_tooltip": "立即清除所有账号的本地限流记录,强制下一次请求尝试直接调用上游。" + "max_wait": "鏈€澶х瓑寰呮椂闀?(绉?", + "max_wait_tooltip": "浠呭湪鈥滅紦瀛樹紭鍏堚€濇ā寮忎笅鐢熸晥锛氬鏋滆处鍙烽檺娴侀噸缃椂闂村皬浜庢鍊硷紝鍒欏師鍦扮瓑寰呰€岄潪鍒囨崲璐﹀彿銆?, + "clear_bindings": "娓呴櫎浼氳瘽缁戝畾", + "clear_bindings_tooltip": "绔嬪嵆鏂紑鎵€鏈変細璇濅笌璐﹀彿鐨勭粦瀹氬叧绯伙紝寮哄埗涓嬩竴娆¤姹傞噸鏂板垎閰嶈处鍙枫€?, + "clear_rate_limits": "娓呴櫎闄愭祦璁板綍", + "clear_rate_limits_tooltip": "绔嬪嵆娓呴櫎鎵€鏈夎处鍙风殑鏈湴闄愭祦璁板綍锛屽己鍒朵笅涓€娆¤姹傚皾璇曠洿鎺ヨ皟鐢ㄤ笂娓搞€? }, "circuit_breaker": { - "title": "自适应熔断器", - "tooltip": "当账号因配额耗尽反复失败时,自动增加锁定时间。这可以防止在死账号上浪费 API 调用,同时允许瞬态错误快速恢复。", - "backoff_levels": "退避等级 (秒)", - "input_placeholder": "输入退避时长 (秒),以逗号分隔", - "level": "等级 {{level}}", - "invalid_format": "格式无效。请使用逗号分隔的数字 (例如 60, 300)", - "clear_records": "清除所有限流记录" + "title": "鑷€傚簲鐔旀柇鍣?, + "tooltip": "褰撹处鍙峰洜閰嶉鑰楀敖鍙嶅澶辫触鏃讹紝鑷姩澧炲姞閿佸畾鏃堕棿銆傝繖鍙互闃叉鍦ㄦ璐﹀彿涓婃氮璐?API 璋冪敤锛屽悓鏃跺厑璁哥灛鎬侀敊璇揩閫熸仮澶嶃€?, + "backoff_levels": "閫€閬跨瓑绾?(绉?", + "input_placeholder": "杈撳叆閫€閬挎椂闀?(绉?锛屼互閫楀彿鍒嗛殧", + "level": "绛夌骇 {{level}}", + "invalid_format": "鏍煎紡鏃犳晥銆傝浣跨敤閫楀彿鍒嗛殧鐨勬暟瀛?(渚嬪 60, 300)", + "clear_records": "娓呴櫎鎵€鏈夐檺娴佽褰? }, "experimental": { - "title": "实验性设置 (Experimental)", - "title_tooltip": "探索性功能,可能在未来版本中调整或移除。", - "enable_usage_scaling": "启用用量缩放", - "enable_usage_scaling_tooltip": "针对 Claude 兼容协议。当总输入超过 30k Token 时开启激进缩放,防止在大上下文下频繁触发客户端压缩。注意:开启后客户端显示的用量不再代表实际计费点数。", - "context_compression_threshold_l1": "L1 压缩阈值 (工具记录清理)", - "context_compression_threshold_l1_tooltip": "清理旧的工具调用记录以节省空间。建议值: 0.4 (40%)", - "context_compression_threshold_l2": "L2 压缩阈值 (思维链压缩)", - "context_compression_threshold_l2_tooltip": "压缩早期的思维链内容,保留签名。建议值: 0.55 (55%)", - "context_compression_threshold_l3": "L3 压缩阈值 (摘要重置)", - "context_compression_threshold_l3_tooltip": "强制生成 XML 状态摘要并重置会话。这是最省 token 的手段。建议值: 0.7 (70%)" + "title": "瀹為獙鎬ц缃?(Experimental)", + "title_tooltip": "鎺㈢储鎬у姛鑳斤紝鍙兘鍦ㄦ湭鏉ョ増鏈腑璋冩暣鎴栫Щ闄ゃ€?, + "enable_usage_scaling": "鍚敤鐢ㄩ噺缂╂斁", + "enable_usage_scaling_tooltip": "閽堝 Claude 鍏煎鍗忚銆傚綋鎬昏緭鍏ヨ秴杩?30k Token 鏃跺紑鍚縺杩涚缉鏀撅紝闃叉鍦ㄥぇ涓婁笅鏂囦笅棰戠箒瑙﹀彂瀹㈡埛绔帇缂┿€傛敞鎰忥細寮€鍚悗瀹㈡埛绔樉绀虹殑鐢ㄩ噺涓嶅啀浠h〃瀹為檯璁¤垂鐐规暟銆?, + "context_compression_threshold_l1": "L1 鍘嬬缉闃堝€?(宸ュ叿璁板綍娓呯悊)", + "context_compression_threshold_l1_tooltip": "娓呯悊鏃х殑宸ュ叿璋冪敤璁板綍浠ヨ妭鐪佺┖闂淬€傚缓璁€? 0.4 (40%)", + "context_compression_threshold_l2": "L2 鍘嬬缉闃堝€?(鎬濈淮閾惧帇缂?", + "context_compression_threshold_l2_tooltip": "鍘嬬缉鏃╂湡鐨勬€濈淮閾惧唴瀹癸紝淇濈暀绛惧悕銆傚缓璁€? 0.55 (55%)", + "context_compression_threshold_l3": "L3 鍘嬬缉闃堝€?(鎽樿閲嶇疆)", + "context_compression_threshold_l3_tooltip": "寮哄埗鐢熸垚 XML 鐘舵€佹憳瑕佸苟閲嶇疆浼氳瘽銆傝繖鏄渶鐪?token 鐨勬墜娈点€傚缓璁€? 0.7 (70%)" }, "opencode_sync": { "card_title": "OpenCode", "status": { - "detecting": "检测中...", - "installed": "已安装 ({{version}})", - "not_installed": "未安装", - "synced": "已同步", - "not_synced": "未同步", - "current_base_url": "当前接口地址 (BASE URL)" + "detecting": "妫€娴嬩腑...", + "installed": "宸插畨瑁?({{version}})", + "not_installed": "鏈畨瑁?, + "synced": "宸插悓姝?, + "not_synced": "鏈悓姝?, + "current_base_url": "褰撳墠鎺ュ彛鍦板潃 (BASE URL)" }, - "sync_accounts": "同步账号到 antigravity-accounts.json", - "btn_sync": "立即同步配置", - "btn_view": "查看配置", - "btn_restore": "还原配置", - "btn_restore_backup": "从备份还原", - "btn_clear": "清除配置", - "clear_confirm_title": "确认清除配置", - "clear_confirm_message": "确定要清除 OpenCode 配置吗?这将删除配置文件。", + "sync_accounts": "鍚屾璐﹀彿鍒?antigravity-accounts.json", + "btn_sync": "绔嬪嵆鍚屾閰嶇疆", + "btn_view": "鏌ョ湅閰嶇疆", + "btn_restore": "杩樺師閰嶇疆", + "btn_restore_backup": "浠庡浠借繕鍘?, + "btn_clear": "娓呴櫎閰嶇疆", + "clear_confirm_title": "纭娓呴櫎閰嶇疆", + "clear_confirm_message": "纭畾瑕佹竻闄?OpenCode 閰嶇疆鍚楋紵杩欏皢鍒犻櫎閰嶇疆鏂囦欢銆?, "toast": { - "config_missing": "请先生成 API Key 并启动服务", - "sync_success": "OpenCode 配置同步成功", - "sync_error": "OpenCode 同步失败: {{error}}", - "clear_success": "OpenCode 配置已清除", - "clear_error": "清除 OpenCode 配置失败: {{error}}" + "config_missing": "璇峰厛鐢熸垚 API Key 骞跺惎鍔ㄦ湇鍔?, + "sync_success": "OpenCode 閰嶇疆鍚屾鎴愬姛", + "sync_error": "OpenCode 鍚屾澶辫触: {{error}}", + "clear_success": "OpenCode 閰嶇疆宸叉竻闄?, + "clear_error": "娓呴櫎 OpenCode 閰嶇疆澶辫触: {{error}}" }, "modal": { - "view_title": "OpenCode 配置文件预览", - "copy_success": "配置已复制" + "view_title": "OpenCode 閰嶇疆鏂囦欢棰勮", + "copy_success": "閰嶇疆宸插鍒? }, - "sync_confirm_title": "确认同步", - "sync_confirm_message": "将根据当前反代设置覆盖 OpenCode 配置。确定继续?", - "restore_confirm": "确定要将 OpenCode 还原为默认配置吗?", - "restore_backup_confirm": "确定要从备份还原 OpenCode 配置吗?", - "modal_title": "选择 OpenCode 模型", - "select_models": "选择要同步的模型", - "auth_plugin_warning": "检测到 opencode-antigravity-auth 插件。同步仅会创建 antigravity-manager provider,不会覆盖 google provider/plugin。", - "btn_confirm_sync": "确认同步", - "custom_base_url_label": "自定义 Manager BaseURL", - "custom_base_url_desc": "适用于 Docker Compose 网络环境", - "custom_base_url_reset": "重置" + "sync_confirm_title": "纭鍚屾", + "sync_confirm_message": "灏嗘牴鎹綋鍓嶅弽浠h缃鐩?OpenCode 閰嶇疆銆傜‘瀹氱户缁紵", + "restore_confirm": "纭畾瑕佸皢 OpenCode 杩樺師涓洪粯璁ら厤缃悧锛?, + "restore_backup_confirm": "纭畾瑕佷粠澶囦唤杩樺師 OpenCode 閰嶇疆鍚楋紵", + "modal_title": "閫夋嫨 OpenCode 妯″瀷", + "select_models": "閫夋嫨瑕佸悓姝ョ殑妯″瀷", + "auth_plugin_warning": "妫€娴嬪埌 opencode-antigravity-auth 鎻掍欢銆傚悓姝ヤ粎浼氬垱寤?antigravity-manager provider锛屼笉浼氳鐩?google provider/plugin銆?, + "btn_confirm_sync": "纭鍚屾", + "custom_base_url_label": "鑷畾涔?Manager BaseURL", + "custom_base_url_desc": "閫傜敤浜?Docker Compose 缃戠粶鐜", + "custom_base_url_reset": "閲嶇疆" }, "droid_sync": { - "modal_title": "添加模型到 Droid", - "modal_desc": "选中的模型将作为 customModels 写入 settings.json", - "selected": "已选", - "btn_confirm_sync": "添加所选模型", + "modal_title": "娣诲姞妯″瀷鍒?Droid", + "modal_desc": "閫変腑鐨勬ā鍨嬪皢浣滀负 customModels 鍐欏叆 settings.json", + "selected": "宸查€?, + "btn_confirm_sync": "娣诲姞鎵€閫夋ā鍨?, "toast": { - "no_models_selected": "请至少选择一个模型", - "sync_success_count": "已添加 {{count}} 个模型到 Droid", - "sync_error": "同步失败: {{error}}" + "no_models_selected": "璇疯嚦灏戦€夋嫨涓€涓ā鍨?, + "sync_success_count": "宸叉坊鍔?{{count}} 涓ā鍨嬪埌 Droid", + "sync_error": "鍚屾澶辫触: {{error}}" } } }, "cloudflared": { - "title": "公网访问 (Cloudflared)", - "subtitle": "通过 Cloudflare 隧道将本地服务暴露到公网", - "not_installed": "Cloudflared 未安装", - "install_hint": "Cloudflared 是 Cloudflare 提供的免费隧道工具,可将本地反代服务暴露到公网,无需公网IP或端口映射。点击下方按钮一键下载安装。", - "install": "一键安装", - "installing": "安装中...", - "install_success": "Cloudflared 安装成功", - "install_failed": "安装失败: {{error}}", - "installed": "已安装", - "version": "版本", - "mode_label": "隧道模式", - "mode_quick": "快速隧道", - "mode_quick_desc": "自动生成临时 URL (*.trycloudflare.com),无需账号,重启后URL会变化", - "mode_auth": "命名隧道", - "mode_auth_desc": "使用 Cloudflare 账号 Token,支持自定义域名,URL固定不变", - "token": "隧道 Token", - "token_placeholder": "粘贴您的 Cloudflare Tunnel Token", - "token_hint": "从 Cloudflare Zero Trust 控制台获取", - "token_required": "命名隧道模式需要提供 Token", - "use_http2": "使用 HTTP/2", - "use_http2_desc": "兼容性更好,推荐中国大陆用户开启", - "status_label": "隧道状态", - "status_stopped": "未运行", - "status_starting": "启动中...", - "status_running": "运行中", - "status_stopping": "停止中...", - "status_error": "错误", - "public_url": "公网地址", - "public_url_placeholder": "隧道启动后将显示公网访问地址", - "copy_url": "复制地址", - "url_copied": "地址已复制", - "start_tunnel": "启动隧道", - "stop_tunnel": "停止隧道", - "running": "隧道运行中", - "started": "隧道已启动", - "stopped": "隧道已停止", - "start_failed": "启动失败: {{error}}", - "stop_failed": "停止失败: {{error}}", - "require_proxy_running": "请先启动本地反代服务,再开启隧道", - "connection_info": "连接信息", - "local_port": "本地端口", - "tunnel_protocol": "隧道协议" + "title": "鍏綉璁块棶 (Cloudflared)", + "subtitle": "閫氳繃 Cloudflare 闅ч亾灏嗘湰鍦版湇鍔℃毚闇插埌鍏綉", + "not_installed": "Cloudflared 鏈畨瑁?, + "install_hint": "Cloudflared 鏄?Cloudflare 鎻愪緵鐨勫厤璐归毀閬撳伐鍏?鍙皢鏈湴鍙嶄唬鏈嶅姟鏆撮湶鍒板叕缃?鏃犻渶鍏綉IP鎴栫鍙f槧灏勩€傜偣鍑讳笅鏂规寜閽竴閿笅杞藉畨瑁呫€?, + "install": "涓€閿畨瑁?, + "installing": "瀹夎涓?..", + "install_success": "Cloudflared 瀹夎鎴愬姛", + "install_failed": "瀹夎澶辫触: {{error}}", + "installed": "宸插畨瑁?, + "version": "鐗堟湰", + "mode_label": "闅ч亾妯″紡", + "mode_quick": "蹇€熼毀閬?, + "mode_quick_desc": "鑷姩鐢熸垚涓存椂 URL (*.trycloudflare.com),鏃犻渶璐﹀彿,閲嶅惎鍚嶶RL浼氬彉鍖?, + "mode_auth": "鍛藉悕闅ч亾", + "mode_auth_desc": "浣跨敤 Cloudflare 璐﹀彿 Token,鏀寔鑷畾涔夊煙鍚?URL鍥哄畾涓嶅彉", + "token": "闅ч亾 Token", + "token_placeholder": "绮樿创鎮ㄧ殑 Cloudflare Tunnel Token", + "token_hint": "浠?Cloudflare Zero Trust 鎺у埗鍙拌幏鍙?, + "token_required": "鍛藉悕闅ч亾妯″紡闇€瑕佹彁渚?Token", + "use_http2": "浣跨敤 HTTP/2", + "use_http2_desc": "鍏煎鎬ф洿濂?鎺ㄨ崘涓浗澶ч檰鐢ㄦ埛寮€鍚?, + "status_label": "闅ч亾鐘舵€?, + "status_stopped": "鏈繍琛?, + "status_starting": "鍚姩涓?..", + "status_running": "杩愯涓?, + "status_stopping": "鍋滄涓?..", + "status_error": "閿欒", + "public_url": "鍏綉鍦板潃", + "public_url_placeholder": "闅ч亾鍚姩鍚庡皢鏄剧ず鍏綉璁块棶鍦板潃", + "copy_url": "澶嶅埗鍦板潃", + "url_copied": "鍦板潃宸插鍒?, + "start_tunnel": "鍚姩闅ч亾", + "stop_tunnel": "鍋滄闅ч亾", + "running": "闅ч亾杩愯涓?, + "started": "闅ч亾宸插惎鍔?, + "stopped": "闅ч亾宸插仠姝?, + "start_failed": "鍚姩澶辫触: {{error}}", + "stop_failed": "鍋滄澶辫触: {{error}}", + "require_proxy_running": "璇峰厛鍚姩鏈湴鍙嶄唬鏈嶅姟,鍐嶅紑鍚毀閬?, + "connection_info": "杩炴帴淇℃伅", + "local_port": "鏈湴绔彛", + "tunnel_protocol": "闅ч亾鍗忚" }, "example": { - "title": "使用示例", + "title": "浣跨敤绀轰緥", "curl": "cURL", "python": "Python", - "python_anthropic": "from anthropic import Anthropic\n\nclient = Anthropic(\n # 推荐使用 127.0.0.1\n base_url=\"{{baseUrl}}\",\n api_key=\"{{apiKey}}\"\n)\n\n# 注意: Antigravity 支持使用 Anthropic SDK 调用任意模型\nresponse = client.messages.create(\n model=\"{{modelId}}\",\n max_tokens=1024,\n messages=[{\"role\": \"user\", \"content\": \"Hello\"}]\n)\n\nprint(response.content[0].text)", - "python_gemini": "# 需要安装: pip install google-generativeai\nimport google.generativeai as genai\n\n# 使用 Antigravity 代理地址 (推荐 127.0.0.1)\ngenai.configure(\n api_key=\"{{apiKey}}\",\n transport='rest',\n client_options={'api_endpoint': '{{rawBaseUrl}}'}\n)\n\nmodel = genai.GenerativeModel('{{modelId}}')\nresponse = model.generate_content(\"Hello\")\nprint(response.text)", - "python_openai_image": "from openai import OpenAI\n\nclient = OpenAI(\n base_url=\"{{baseUrl}}\",\n api_key=\"{{apiKey}}\"\n)\n\nresponse = client.chat.completions.create(\n model=\"{{modelId}}\",\n # 方式 1: 使用 size 参数 (推荐)\n # 支持: \"1024x1024\" (1:1), \"1280x720\" (16:9), \"720x1280\" (9:16), \"1216x896\" (4:3)\n extra_body={ \"size\": \"1024x1024\" },\n\n # 方式 2: 使用模型后缀\n # 例如: gemini-3-pro-image-16-9, gemini-3-pro-image-4-3\n # model=\"gemini-3-pro-image-16-9\",\n messages=[{\n \"role\": \"user\",\n \"content\": \"画一个未来城市\"\n }]\n)\n\nprint(response.choices[0].message.content)", + "python_anthropic": "from anthropic import Anthropic\n\nclient = Anthropic(\n # 鎺ㄨ崘浣跨敤 127.0.0.1\n base_url=\"{{baseUrl}}\",\n api_key=\"{{apiKey}}\"\n)\n\n# 娉ㄦ剰: Antigravity 鏀寔浣跨敤 Anthropic SDK 璋冪敤浠绘剰妯″瀷\nresponse = client.messages.create(\n model=\"{{modelId}}\",\n max_tokens=1024,\n messages=[{\"role\": \"user\", \"content\": \"Hello\"}]\n)\n\nprint(response.content[0].text)", + "python_gemini": "# 闇€瑕佸畨瑁? pip install google-generativeai\nimport google.generativeai as genai\n\n# 浣跨敤 Antigravity 浠g悊鍦板潃 (鎺ㄨ崘 127.0.0.1)\ngenai.configure(\n api_key=\"{{apiKey}}\",\n transport='rest',\n client_options={'api_endpoint': '{{rawBaseUrl}}'}\n)\n\nmodel = genai.GenerativeModel('{{modelId}}')\nresponse = model.generate_content(\"Hello\")\nprint(response.text)", + "python_openai_image": "from openai import OpenAI\n\nclient = OpenAI(\n base_url=\"{{baseUrl}}\",\n api_key=\"{{apiKey}}\"\n)\n\nresponse = client.chat.completions.create(\n model=\"{{modelId}}\",\n # 鏂瑰紡 1: 浣跨敤 size 鍙傛暟 (鎺ㄨ崘)\n # 鏀寔: \"1024x1024\" (1:1), \"1280x720\" (16:9), \"720x1280\" (9:16), \"1216x896\" (4:3)\n extra_body={ \"size\": \"1024x1024\" },\n\n # 鏂瑰紡 2: 浣跨敤妯″瀷鍚庣紑\n # 渚嬪: gemini-3-pro-image-16-9, gemini-3-pro-image-4-3\n # model=\"gemini-3-pro-image-16-9\",\n messages=[{\n \"role\": \"user\",\n \"content\": \"鐢讳竴涓湭鏉ュ煄甯俓"\n }]\n)\n\nprint(response.choices[0].message.content)", "python_openai": "from openai import OpenAI\n\nclient = OpenAI(\n base_url=\"{{baseUrl}}\",\n api_key=\"{{apiKey}}\"\n)\n\nresponse = client.chat.completions.create(\n model=\"{{modelId}}\",\n messages=[{\"role\": \"user\", \"content\": \"Hello\"}]\n)\n\nprint(response.choices[0].message.content)" }, "dialog": { - "confirm_regenerate": "确定要生成新的 API Key 吗?旧的 Key 将立即失效。", - "operate_failed": "操作失败: {{error}}", - "reset_mapping_title": "重置模型映射", - "reset_mapping_msg": "确定要重置所有模型映射为系统默认吗?此操作无法撤销。", - "regenerate_key_title": "重新生成 API Key", - "regenerate_key_msg": "确定要重新生成 API Key 吗?旧的 Key 将立即失效。", - "clear_bindings_title": "清除会话绑定", - "clear_bindings_msg": "确定要清除所有会话与账号的绑定映射吗?", - "clear_rate_limits_title": "清除限流记录", - "clear_rate_limits_confirm": "确定要清除所有本地限流记录吗?" + "confirm_regenerate": "纭畾瑕佺敓鎴愭柊鐨?API Key 鍚楋紵鏃х殑 Key 灏嗙珛鍗冲け鏁堛€?, + "operate_failed": "鎿嶄綔澶辫触: {{error}}", + "reset_mapping_title": "閲嶇疆妯″瀷鏄犲皠", + "reset_mapping_msg": "纭畾瑕侀噸缃墍鏈夋ā鍨嬫槧灏勪负绯荤粺榛樿鍚楋紵姝ゆ搷浣滄棤娉曟挙閿€銆?, + "regenerate_key_title": "閲嶆柊鐢熸垚 API Key", + "regenerate_key_msg": "纭畾瑕侀噸鏂扮敓鎴?API Key 鍚楋紵鏃х殑 Key 灏嗙珛鍗冲け鏁堛€?, + "clear_bindings_title": "娓呴櫎浼氳瘽缁戝畾", + "clear_bindings_msg": "纭畾瑕佹竻闄ゆ墍鏈変細璇濅笌璐﹀彿鐨勭粦瀹氭槧灏勫悧锛?, + "clear_rate_limits_title": "娓呴櫎闄愭祦璁板綍", + "clear_rate_limits_confirm": "纭畾瑕佹竻闄ゆ墍鏈夋湰鍦伴檺娴佽褰曞悧锛? }, "model": { - "flash": "极速响应", - "flash_preview": "极速预览 (Flash 3.1)", - "flash_lite": "轻量极速 (Lite)", - "flash_thinking": "思考能力 (Thinking)", - "pro_legacy": "经典版 Pro", + "flash": "鏋侀€熷搷搴?, + "flash_preview": "鏋侀€熼瑙?(Flash 3.1)", + "flash_lite": "杞婚噺鏋侀€?(Lite)", + "flash_thinking": "鎬濊€冭兘鍔?(Thinking)", + "pro_legacy": "缁忓吀鐗?Pro", "pro_low": "3.1 Pro Low", "pro_high": "3.1 Pro High", - "pro_image": "图片生成 (1:1)", - "pro_image_16_9": "图片生成 (16:9)", - "pro_image_9_16": "图片生成 (9:16)", - "pro_image_4_3": "图片生成 (4:3)", - "pro_image_3_4": "图片生成 (3:4)", - "pro_image_1_1": "图片生成 (1:1)", - "claude_sonnet": "代码推理 (Claude 4.6)", - "claude_sonnet_thinking": "思维链 (4.6 Think)", - "claude_opus_thinking": "最强思维 (Opus Think)", - "gemini_2_5_flash": "极速模型 (2.5 Flash)", - "gemini_2_5_pro": "高性能推理 (2.5 Pro)", - "claude_4_6": "最新代理版 (4.6)" + "pro_image": "鍥剧墖鐢熸垚 (1:1)", + "pro_image_16_9": "鍥剧墖鐢熸垚 (16:9)", + "pro_image_9_16": "鍥剧墖鐢熸垚 (9:16)", + "pro_image_4_3": "鍥剧墖鐢熸垚 (4:3)", + "pro_image_3_4": "鍥剧墖鐢熸垚 (3:4)", + "pro_image_1_1": "鍥剧墖鐢熸垚 (1:1)", + "claude_sonnet": "浠g爜鎺ㄧ悊 (Claude 4.6)", + "claude_sonnet_thinking": "鎬濈淮閾?(4.6 Think)", + "claude_opus_thinking": "鏈€寮烘€濈淮 (Opus Think)", + "gemini_2_5_flash": "鏋侀€熸ā鍨?(2.5 Flash)", + "gemini_2_5_pro": "楂樻€ц兘鎺ㄧ悊 (2.5 Pro)", + "claude_4_6": "鏈€鏂颁唬鐞嗙増 (4.6)" }, "mapping": { - "title": "Claude Code 模型映射", - "description": "将 Claude Code 模型映射到 Antigravity 模型,智能路由请求以优化成本和速度。", - "default": "默认", - "sonnet_desc": "最强复杂任务", - "opus_desc": "高级层级", - "haiku_desc": "极速响应", - "maps_to": "映射到 Antigravity", - "apply_recommended": "应用推荐配置", - "restore_defaults": "恢复默认配置", - "reset_all": "重置全部" + "title": "Claude Code 妯″瀷鏄犲皠", + "description": "灏?Claude Code 妯″瀷鏄犲皠鍒?Antigravity 妯″瀷,鏅鸿兘璺敱璇锋眰浠ヤ紭鍖栨垚鏈拰閫熷害銆?, + "default": "榛樿", + "sonnet_desc": "鏈€寮哄鏉備换鍔?, + "opus_desc": "楂樼骇灞傜骇", + "haiku_desc": "鏋侀€熷搷搴?, + "maps_to": "鏄犲皠鍒?Antigravity", + "apply_recommended": "搴旂敤鎺ㄨ崘閰嶇疆", + "restore_defaults": "鎭㈠榛樿閰嶇疆", + "reset_all": "閲嶇疆鍏ㄩ儴" }, "models": { - "flash": "极速响应", - "flash_thinking": "思考能力", - "pro_high": "最强推理", - "pro_low": "低配额", - "sonnet": "代码推理", - "sonnet_thinking": "思维链", - "opus_thinking": "最强思维" + "flash": "鏋侀€熷搷搴?, + "flash_thinking": "鎬濊€冭兘鍔?, + "pro_high": "鏈€寮烘帹鐞?, + "pro_low": "浣庨厤棰?, + "sonnet": "浠g爜鎺ㄧ悊", + "sonnet_thinking": "鎬濈淮閾?, + "opus_thinking": "鏈€寮烘€濈淮" }, "router": { - "title": "模型路由中心 (Model Router)", - "subtitle": "按“规格家族”统一路由 OpenAI/Claude 模型,或添加最高优先级的“精确映射”。\n注意:Claude 原生直通模型(claude-sonnet-4-6-thinking, claude-opus-4-6-thinking 等)默认透传,需在“专家精确映射”中添加规则才能修改。", - "subtitle_simple": "通过通配符或精确映射自定义模型路由规则", - "background_task_title": "后台任务模型", - "background_task_desc": "用于 Claude CLI 的标题生成、摘要提取等后台自动化任务 (默认: gemini-2.5-flash)", - "use_default": "使用系统默认", - "current_model": "当前模型", - "apply_presets": "应用预设映射", - "presets_applied": "预设映射已应用", - "preset_default": "默认预设", - "preset_default_desc": "GPT-4 → Gemini Pro, Claude → Opus", - "preset_performance": "性能优先", - "preset_performance_desc": "全部使用高性能模型", - "preset_cost": "成本优化", - "preset_cost_desc": "优先使用经济型模型", - "preset_balanced": "均衡模式", - "preset_balanced_desc": "平衡性能和成本", - "built_in_presets": "内置预设", - "custom_presets": "自定义预设", - "apply_selected": "应用所选", - "add_preset": "保存当前映射", - "delete_preset": "删除当前预设", - "cannot_delete_builtin": "无法删除内置预设", - "no_mapping_to_save": "没有可保存的映射配置", - "preset_name_required": "请先输入预设名称", - "preset_saved": "预设保存成功", - "manage_presets_title": "管理自定义预设", - "save_current_as_preset": "保存当前配置", - "preset_name_placeholder": "输入预设名称...", - "save_hint": "将当前激活的模型映射保存为可重复使用的预设。", - "your_presets": "您的预设", - "no_custom_presets": "暂无自定义预设", - "mappings_count": "个映射", - "custom_preset_desc": "用户自定义预设", - "custom_mappings": "自定义映射 (Custom Mappings)", - "original_id": "原始模型 ID", - "route_to": "路由目标", - "group_title": "模型家族分组 (Series Groups)", - "gemini3_group_label": "Gemini 3 (推荐)", - "gemini3_option_high": "gemini-3.1-pro-high (高质量)", - "gemini3_option_low": "gemini-3.1-pro-low (均衡)", - "gemini3_option_flash": "gemini-3-flash (快速)", + "title": "妯″瀷璺敱涓績 (Model Router)", + "subtitle": "鎸夆€滆鏍煎鏃忊€濈粺涓€璺敱 OpenAI/Claude 妯″瀷锛屾垨娣诲姞鏈€楂樹紭鍏堢骇鐨勨€滅簿纭槧灏勨€濄€俓n娉ㄦ剰锛欳laude 鍘熺敓鐩撮€氭ā鍨嬶紙claude-sonnet-4-6-thinking, claude-opus-4-6-thinking 绛夛級榛樿閫忎紶锛岄渶鍦ㄢ€滀笓瀹剁簿纭槧灏勨€濅腑娣诲姞瑙勫垯鎵嶈兘淇敼銆?, + "subtitle_simple": "閫氳繃閫氶厤绗︽垨绮剧‘鏄犲皠鑷畾涔夋ā鍨嬭矾鐢辫鍒?, + "background_task_title": "鍚庡彴浠诲姟妯″瀷", + "background_task_desc": "鐢ㄤ簬 Claude CLI 鐨勬爣棰樼敓鎴愩€佹憳瑕佹彁鍙栫瓑鍚庡彴鑷姩鍖栦换鍔?(榛樿: gemini-2.5-flash)", + "use_default": "浣跨敤绯荤粺榛樿", + "current_model": "褰撳墠妯″瀷", + "apply_presets": "搴旂敤棰勮鏄犲皠", + "presets_applied": "棰勮鏄犲皠宸插簲鐢?, + "preset_default": "榛樿棰勮", + "preset_default_desc": "GPT-4 鈫?Gemini Pro, Claude 鈫?Opus", + "preset_performance": "鎬ц兘浼樺厛", + "preset_performance_desc": "鍏ㄩ儴浣跨敤楂樻€ц兘妯″瀷", + "preset_cost": "鎴愭湰浼樺寲", + "preset_cost_desc": "浼樺厛浣跨敤缁忔祹鍨嬫ā鍨?, + "preset_balanced": "鍧囪 妯″紡", + "preset_balanced_desc": "骞宠 鎬ц兘鍜屾垚鏈?, + "built_in_presets": "鍐呯疆棰勮", + "custom_presets": "鑷畾涔夐璁?, + "apply_selected": "搴旂敤鎵€閫?, + "add_preset": "淇濆瓨褰撳墠鏄犲皠", + "delete_preset": "鍒犻櫎褰撳墠棰勮", + "cannot_delete_builtin": "鏃犳硶鍒犻櫎鍐呯疆棰勮", + "no_mapping_to_save": "娌℃湁鍙繚瀛樼殑鏄犲皠閰嶇疆", + "preset_name_required": "璇峰厛杈撳叆棰勮鍚嶇О", + "preset_saved": "棰勮淇濆瓨鎴愬姛", + "manage_presets_title": "绠$悊鑷畾涔夐璁?, + "save_current_as_preset": "淇濆瓨褰撳墠閰嶇疆", + "preset_name_placeholder": "杈撳叆棰勮鍚嶇О...", + "save_hint": "灏嗗綋鍓嶆縺娲荤殑妯″瀷鏄犲皠淇濆瓨涓哄彲閲嶅浣跨敤鐨勯璁俱€?, + "your_presets": "鎮ㄧ殑棰勮", + "no_custom_presets": "鏆傛棤鑷畾涔夐璁?, + "mappings_count": "涓槧灏?, + "custom_preset_desc": "鐢ㄦ埛鑷畾涔夐璁?, + "custom_mappings": "鑷畾涔夋槧灏?(Custom Mappings)", + "original_id": "鍘熷妯″瀷 ID", + "route_to": "璺敱鐩爣", + "group_title": "妯″瀷瀹舵棌鍒嗙粍 (Series Groups)", + "gemini3_group_label": "Gemini 3 (鎺ㄨ崘)", + "gemini3_option_high": "gemini-3.1-pro-high (楂樿川閲?", + "gemini3_option_low": "gemini-3.1-pro-low (鍧囪 )", + "gemini3_option_flash": "gemini-3-flash (蹇€?", "groups": { "claude_45": { - "name": "Opus 4.6 TK 系列", - "desc": "Opus 4.5 TK (推理)" + "name": "Opus 4.6 TK 绯诲垪", + "desc": "Opus 4.5 TK (鎺ㄧ悊)" }, "claude_35": { - "name": "Claude 3.5 系列", + "name": "Claude 3.5 绯诲垪", "desc": "Sonnet 3.5, Haiku 3.5" }, "gpt_4": { - "name": "GPT-4 / o1 系列", + "name": "GPT-4 / o1 绯诲垪", "desc": "GPT-4, Turbo, o1-preview" }, "gpt_4o": { - "name": "GPT-4o / 3.5 系列", + "name": "GPT-4o / 3.5 绯诲垪", "desc": "GPT-4o, Mini, 3.5 Turbo" }, "gpt_5": { - "name": "GPT-5 系列", + "name": "GPT-5 绯诲垪", "desc": "GPT-5.1, GPT-5.2 xhigh" } }, - "expert_title": "专家精确映射", - "expert_subtitle": "精确匹配支持从任何协议传来的原始模型 ID。", - "custom_mapping_tip": "💡 支持手动输入任意模型 ID,可体验未发布模型(如 claude-opus-4-6)。", - "custom_mapping_warning": "注意:并非所有账号都支持未发布模型。", - "money_saving_tip": "💰 省钱提示:", - "haiku_optimization_tip": "Claude CLI 默认使用 {{model}} 处理后台任务,建议映射到廉价 Flash 模型可节省约 95% 成本", - "haiku_optimization_btn": "一键优化", - "haiku_tip_title": "💰 省钱提示:", - "haiku_tip_body_before": "Claude CLI 默认使用", - "haiku_tip_body_after": "处理后台任务,建议映射到廉价 Flash 模型可节省约 95% 成本", - "haiku_tip_action": "一键优化", - "reset_confirm": "确定要重置所有模型映射为系统默认吗?", - "reset_mapping": "重置映射", - "add_mapping": "添加映射 (Add Mapping)", - "current_list": "当前映射列表 (Custom List)", - "no_custom_mapping": "暂无自定义精确映射", - "gemini3_only_warning": "⚠️ 仅支持 Gemini 3 系列", - "default_suffix": "(默认)", - "select_target_model": "选择目标模型", - "original_placeholder": "原始名 (如 gpt-4 或 gpt-4*)" + "expert_title": "涓撳绮剧‘鏄犲皠", + "expert_subtitle": "绮剧‘鍖归厤鏀寔浠庝换浣曞崗璁紶鏉ョ殑鍘熷妯″瀷 ID銆?, + "custom_mapping_tip": "馃挕 鏀寔鎵嬪姩杈撳叆浠绘剰妯″瀷 ID,鍙綋楠屾湭鍙戝竷妯″瀷(濡?claude-opus-4-6)銆?, + "custom_mapping_warning": "娉ㄦ剰:骞堕潪鎵€鏈夎处鍙烽兘鏀寔鏈彂甯冩ā鍨嬨€?, + "money_saving_tip": "馃挵 鐪侀挶鎻愮ず:", + "haiku_optimization_tip": "Claude CLI 榛樿浣跨敤 {{model}} 澶勭悊鍚庡彴浠诲姟,寤鸿鏄犲皠鍒板粔浠?Flash 妯″瀷鍙妭鐪佺害 95% 鎴愭湰", + "haiku_optimization_btn": "涓€閿紭鍖?, + "haiku_tip_title": "馃挵 鐪侀挶鎻愮ず:", + "haiku_tip_body_before": "Claude CLI 榛樿浣跨敤", + "haiku_tip_body_after": "澶勭悊鍚庡彴浠诲姟,寤鸿鏄犲皠鍒板粔浠?Flash 妯″瀷鍙妭鐪佺害 95% 鎴愭湰", + "haiku_tip_action": "涓€閿紭鍖?, + "reset_confirm": "纭畾瑕侀噸缃墍鏈夋ā鍨嬫槧灏勪负绯荤粺榛樿鍚楋紵", + "reset_mapping": "閲嶇疆鏄犲皠", + "add_mapping": "娣诲姞鏄犲皠 (Add Mapping)", + "current_list": "褰撳墠鏄犲皠鍒楄〃 (Custom List)", + "no_custom_mapping": "鏆傛棤鑷畾涔夌簿纭槧灏?, + "gemini3_only_warning": "鈿狅笍 浠呮敮鎸?Gemini 3 绯诲垪", + "default_suffix": "锛堥粯璁わ級", + "select_target_model": "閫夋嫨鐩爣妯″瀷", + "original_placeholder": "鍘熷鍚?(濡?gpt-4 鎴?gpt-4*)" }, "examples": { - "title": "使用示例" + "title": "浣跨敤绀轰緥" }, "multi_protocol": { - "title": "多协议支持 (Multi-Protocol Support)", - "subtitle": "快速同步 API 地址与密钥到本地 AI 工具", - "description": "反代服务支持 OpenAI、Anthropic 和 Gemini 协议,满足不同工具的集成需求", - "openai_label": "OpenAI 协议", - "anthropic_label": "Anthropic 协议", + "title": "澶氬崗璁敮鎸?(Multi-Protocol Support)", + "subtitle": "蹇€熷悓姝?API 鍦板潃涓庡瘑閽ュ埌鏈湴 AI 宸ュ叿", + "description": "鍙嶄唬鏈嶅姟鏀寔 OpenAI銆丄nthropic 鍜?Gemini 鍗忚锛屾弧瓒充笉鍚屽伐鍏风殑闆嗘垚闇€姹?, + "openai_label": "OpenAI 鍗忚", + "anthropic_label": "Anthropic 鍗忚", "openai_tools": "Cherry Studio, NextChat", "anthropic_tools": "Claude Code CLI", - "gemini_label": "Gemini 协议", + "gemini_label": "Gemini 鍗忚", "gemini_tools": "Google AI SDK, LangChain", - "quick_integration": "快速集成 (Quick Integration)", - "click_tip": "👆 点击模型以更新代码示例", - "copy_base": "复制 Base" + "quick_integration": "蹇€熼泦鎴?(Quick Integration)", + "click_tip": "馃憜 鐐瑰嚮妯″瀷浠ユ洿鏂颁唬鐮佺ず渚?, + "copy_base": "澶嶅埗 Base" }, "supported_models": { - "title": "支持模型与集成 (Supported Models & Integration)", - "model_name": "模型名称", - "model_id": "模型 ID", - "description": "描述", - "action": "操作" + "title": "鏀寔妯″瀷涓庨泦鎴?(Supported Models & Integration)", + "model_name": "妯″瀷鍚嶇О", + "model_id": "妯″瀷 ID", + "description": "鎻忚堪", + "action": "鎿嶄綔" }, "cli_sync": { - "title": "CLI 配置一键同步", - "subtitle": "快速将当前 API 服务地址与 API 密钥同步到本地 AI CLI 工具中", - "card_title": "{{name}} 配置", + "title": "CLI 閰嶇疆涓€閿悓姝?, + "subtitle": "蹇€熷皢褰撳墠 API 鏈嶅姟鍦板潃涓?API 瀵嗛挜鍚屾鍒版湰鍦?AI CLI 宸ュ叿涓?, + "card_title": "{{name}} 閰嶇疆", "status": { - "not_installed": "未检测到安装", + "not_installed": "鏈娴嬪埌瀹夎", "installed": "v{{version}}", - "synced": "已指向本项目", - "not_synced": "未同步", - "detecting": "检测中...", - "current_base_url": "当前接口地址 (Base URL)" + "synced": "宸叉寚鍚戞湰椤圭洰", + "not_synced": "鏈悓姝?, + "detecting": "妫€娴嬩腑...", + "current_base_url": "褰撳墠鎺ュ彛鍦板潃 (Base URL)" }, - "model_select": "选择同步模型", - "btn_sync": "立即同步配置", - "btn_view": "查看当前配置", - "btn_restore": "恢复默认配置", - "btn_restore_backup": "恢复原有配置", - "restore_confirm": "确定要将 {{name}} 的配置恢复为官方默认地址吗?", - "restore_backup_confirm": "检测到旧的配置文件备份,确定要还原吗?", + "model_select": "閫夋嫨鍚屾妯″瀷", + "btn_sync": "绔嬪嵆鍚屾閰嶇疆", + "btn_view": "鏌ョ湅褰撳墠閰嶇疆", + "btn_restore": "鎭㈠榛樿閰嶇疆", + "btn_restore_backup": "鎭㈠鍘熸湁閰嶇疆", + "restore_confirm": "纭畾瑕佸皢 {{name}} 鐨勯厤缃仮澶嶄负瀹樻柟榛樿鍦板潃鍚楋紵", + "restore_backup_confirm": "妫€娴嬪埌鏃х殑閰嶇疆鏂囦欢澶囦唤锛岀‘瀹氳杩樺師鍚楋紵", "modal": { - "view_title": "{{name}} 配置文件内容", - "copy_success": "配置内容已复制" + "view_title": "{{name}} 閰嶇疆鏂囦欢鍐呭", + "copy_success": "閰嶇疆鍐呭宸插鍒? }, "toast": { - "sync_success": "同步成功!{{name}} 已准备就绪。", - "sync_error": "同步失败:{{error}}" + "sync_success": "鍚屾鎴愬姛锛亄{name}} 宸插噯澶囧氨缁€?, + "sync_error": "鍚屾澶辫触锛歿{error}}" }, - "sync_confirm_title": "同步确认", - "sync_confirm_message": "即将为您同步 {{name}} 的配置。⚠️ 注意:此操作将覆盖您本地已有的配置文件(如登录状态、API Key 等)。确定要继续吗?" + "sync_confirm_title": "鍚屾纭", + "sync_confirm_message": "鍗冲皢涓烘偍鍚屾 {{name}} 鐨勯厤缃€傗殸锔?娉ㄦ剰锛氭鎿嶄綔灏嗚鐩栨偍鏈湴宸叉湁鐨勯厤缃枃浠讹紙濡傜櫥褰曠姸鎬併€丄PI Key 绛夛級銆傜‘瀹氳缁х画鍚楋紵" } }, "monitor": { - "page_title": "API 监控看板", - "page_subtitle": "实时请求日志与分析", - "open_monitor": "打开监控", + "page_title": "API 鐩戞帶鐪嬫澘", + "page_subtitle": "瀹炴椂璇锋眰鏃ュ織涓庡垎鏋?, + "open_monitor": "鎵撳紑鐩戞帶", "logging_status": { - "active": "正在录制", - "paused": "已暂停" + "active": "姝e湪褰曞埗", + "paused": "宸叉殏鍋? }, "stats": { - "total": "总计", - "ok": "正常", - "err": "错误" + "total": "鎬昏", + "ok": "姝e父", + "err": "閿欒" }, "filters": { - "placeholder": "搜索模型 (gemini, claude)、路径 (chat, images) 或状态码...", - "quick_filters": "快速过滤:", - "all": "全部", - "error": "仅错误", - "chat": "聊天", + "placeholder": "鎼滅储妯″瀷 (gemini, claude)銆佽矾寰?(chat, images) 鎴栫姸鎬佺爜...", + "quick_filters": "蹇€熻繃婊?", + "all": "鍏ㄩ儴", + "error": "浠呴敊璇?, + "chat": "鑱婂ぉ", "gemini": "Gemini", "claude": "Claude", - "images": "绘图", - "reset": "重置", - "by_account": "按账号筛选", - "all_accounts": "全部账号" + "images": "缁樺浘", + "reset": "閲嶇疆", + "by_account": "鎸夎处鍙风瓫閫?, + "all_accounts": "鍏ㄩ儴璐﹀彿" }, "table": { - "status": "状态", - "method": "方法", - "model": "模型", - "protocol": "协议", - "account": "账号", - "path": "路径", - "usage": "Token 消耗", - "duration": "耗时", - "time": "时间", - "empty": "暂无请求记录" + "status": "鐘舵€?, + "method": "鏂规硶", + "model": "妯″瀷", + "protocol": "鍗忚", + "account": "璐﹀彿", + "path": "璺緞", + "usage": "Token 娑堣€?, + "duration": "鑰楁椂", + "time": "鏃堕棿", + "empty": "鏆傛棤璇锋眰璁板綍" }, "details": { - "title": "请求详情", - "request_payload": "请求报文 (Request)", - "response_payload": "响应报文 (Response)", - "duration": "耗时", - "tokens": "Token 消耗 (输入/输出)", - "time": "请求时间", - "model": "使用模型", - "mapped_model": "映射模型", - "protocol": "请求协议", - "account_used": "使用账号", - "id": "请求 ID", - "payload_empty": "无数据" + "title": "璇锋眰璇︽儏", + "request_payload": "璇锋眰鎶ユ枃 (Request)", + "response_payload": "鍝嶅簲鎶ユ枃 (Response)", + "duration": "鑰楁椂", + "tokens": "Token 娑堣€?(杈撳叆/杈撳嚭)", + "time": "璇锋眰鏃堕棿", + "model": "浣跨敤妯″瀷", + "mapped_model": "鏄犲皠妯″瀷", + "protocol": "璇锋眰鍗忚", + "account_used": "浣跨敤璐﹀彿", + "id": "璇锋眰 ID", + "payload_empty": "鏃犳暟鎹? }, "dialog": { - "clear_title": "清除监控日志", - "clear_msg": "确定要清除所有监控记录吗?此操作无法撤销。" + "clear_title": "娓呴櫎鐩戞帶鏃ュ織", + "clear_msg": "纭畾瑕佹竻闄ゆ墍鏈夌洃鎺ц褰曞悧锛熸鎿嶄綔鏃犳硶鎾ら攢銆? } }, "update_notification": { - "title": "发现新版本", - "message": "新版本已准备就绪,包含诸多优化与改进。当前版本: v{{current}}", - "ready": "更新准备就绪", - "downloading": "正在下载更新...", - "restarting": "正在重启应用...", - "auto_update": "自动更新", + "title": "鍙戠幇鏂扮増鏈?, + "message": "鏂扮増鏈凡鍑嗗灏辩华锛屽寘鍚澶氫紭鍖栦笌鏀硅繘銆傚綋鍓嶇増鏈? v{{current}}", + "ready": "鏇存柊鍑嗗灏辩华", + "downloading": "姝e湪涓嬭浇鏇存柊...", + "restarting": "姝e湪閲嶅惎搴旂敤...", + "auto_update": "鑷姩鏇存柊", "toast": { - "not_ready": "自动更新包尚未就绪,为您跳转到下载页面...", - "failed": "自动更新失败,为您跳转到下载页面..." + "not_ready": "鑷姩鏇存柊鍖呭皻鏈氨缁紝涓烘偍璺宠浆鍒颁笅杞介〉闈?..", + "failed": "鑷姩鏇存柊澶辫触锛屼负鎮ㄨ烦杞埌涓嬭浇椤甸潰..." } }, "login": { - "title": "安全访问控制", - "desc": "当前运行在 Web 模式下,请输入管理密码或 API Key 以进入后台。", - "placeholder": "请输入管理密码或 API Key", - "btn_login": "验证并进入", - "btn_verifying": "验证中...", - "error_invalid_key": "密码或 API Key 错误,请重试", - "error_network": "网络连接失败,请检查服务是否正常运行", - "note": "注意:如果设置了独立的管理密码,请输入管理密码;否则请输入 API_KEY。", - "lookup_hint": "如果您忘记了,请运行 docker logs antigravity-manager 寻找 Current API Key 或 Web UI Password", - "config_hint": "或执行 grep -E '\"api_key\"|\"admin_password\"' ~/.antigravity_tools/gui_config.json 查看。" + "title": "瀹夊叏璁块棶鎺у埗", + "desc": "褰撳墠杩愯鍦?Web 妯″紡涓嬶紝璇疯緭鍏ョ鐞嗗瘑鐮佹垨 API Key 浠ヨ繘鍏ュ悗鍙般€?, + "placeholder": "璇疯緭鍏ョ鐞嗗瘑鐮佹垨 API Key", + "btn_login": "楠岃瘉骞惰繘鍏?, + "btn_verifying": "楠岃瘉涓?..", + "error_invalid_key": "瀵嗙爜鎴?API Key 閿欒锛岃閲嶈瘯", + "error_network": "缃戠粶杩炴帴澶辫触锛岃妫€鏌ユ湇鍔℃槸鍚︽甯歌繍琛?, + "note": "娉ㄦ剰锛氬鏋滆缃簡鐙珛鐨勭鐞嗗瘑鐮侊紝璇疯緭鍏ョ鐞嗗瘑鐮侊紱鍚﹀垯璇疯緭鍏?API_KEY銆?, + "lookup_hint": "请查看 gui_config.json 或检查环境变量以获取它们。", + "config_hint": "鎴栨墽琛?grep -E '\"api_key\"|\"admin_password\"' ~/.antigravity_tools/gui_config.json 鏌ョ湅銆? }, "token_stats": { - "title": "Token 消费统计", - "hourly": "小时", - "daily": "日", - "weekly": "周", - "total_tokens": "总 Token", - "input_tokens": "输入 Token", - "output_tokens": "输出 Token", - "accounts_used": "活跃账号", - "models_used": "使用模型", - "model_trend": "分模型使用趋势", - "account_trend": "分账号使用趋势", - "usage_trend": "Token 使用趋势", - "by_account": "分账号统计", - "by_model": "按模型", - "by_account_view": "按账号", - "model_details": "分模型详细统计", - "account_details": "账号详细统计", - "model": "模型", - "account": "账号", - "requests": "请求数", - "input": "输入", - "output": "输出", - "total": "合计", - "percentage": "占比", - "no_data": "暂无数据" + "title": "Token 娑堣垂缁熻", + "hourly": "灏忔椂", + "daily": "鏃?, + "weekly": "鍛?, + "total_tokens": "鎬?Token", + "input_tokens": "杈撳叆 Token", + "output_tokens": "杈撳嚭 Token", + "accounts_used": "娲昏穬璐﹀彿", + "models_used": "浣跨敤妯″瀷", + "model_trend": "鍒嗘ā鍨嬩娇鐢ㄨ秼鍔?, + "account_trend": "鍒嗚处鍙蜂娇鐢ㄨ秼鍔?, + "usage_trend": "Token 浣跨敤瓒嬪娍", + "by_account": "鍒嗚处鍙风粺璁?, + "by_model": "鎸夋ā鍨?, + "by_account_view": "鎸夎处鍙?, + "model_details": "鍒嗘ā鍨嬭缁嗙粺璁?, + "account_details": "璐﹀彿璇︾粏缁熻", + "model": "妯″瀷", + "account": "璐﹀彿", + "requests": "璇锋眰鏁?, + "input": "杈撳叆", + "output": "杈撳嚭", + "total": "鍚堣", + "percentage": "鍗犳瘮", + "no_data": "鏆傛棤鏁版嵁" }, "errors": { "stream": { - "timeout_error": "请求超时,请检查网络连接", - "connection_error": "无法连接到服务器,请检查网络或代理设置", - "decode_error": "网络连接不稳定,数据传输中断。建议: 1) 检查网络连接 2) 更换代理节点 3) 稍后重试", - "stream_error": "数据流传输错误,请稍后重试", - "unknown_error": "发生未知错误,请稍后重试" + "timeout_error": "璇锋眰瓒呮椂,璇锋鏌ョ綉缁滆繛鎺?, + "connection_error": "鏃犳硶杩炴帴鍒版湇鍔″櫒,璇锋鏌ョ綉缁滄垨浠g悊璁剧疆", + "decode_error": "缃戠粶杩炴帴涓嶇ǔ瀹?鏁版嵁浼犺緭涓柇銆傚缓璁? 1) 妫€鏌ョ綉缁滆繛鎺?2) 鏇存崲浠g悊鑺傜偣 3) 绋嶅悗閲嶈瘯", + "stream_error": "鏁版嵁娴佷紶杈撻敊璇?璇风◢鍚庨噸璇?, + "unknown_error": "鍙戠敓鏈煡閿欒,璇风◢鍚庨噸璇? } }, "security": { - "title": "安全监控", - "refresh_data": "刷新数据", - "refresh": "刷新", - "tab_logs": "访问日志", - "tab_stats": "统计分析", - "tab_blacklist": "黑名单管理", - "tab_whitelist": "白名单管理", - "tab_config": "安全配置", + "title": "瀹夊叏鐩戞帶", + "refresh_data": "鍒锋柊鏁版嵁", + "refresh": "鍒锋柊", + "tab_logs": "璁块棶鏃ュ織", + "tab_stats": "缁熻鍒嗘瀽", + "tab_blacklist": "榛戝悕鍗曠鐞?, + "tab_whitelist": "鐧藉悕鍗曠鐞?, + "tab_config": "瀹夊叏閰嶇疆", "stats": { - "total_requests": "总请求数", - "total_requests_desc": "所有记录的请求", - "unique_ips": "独立 IP 数", - "unique_ips_desc": "不同的客户端 IP 地址", - "blocked_requests": "拦截请求数", - "blocked_requests_desc": "被规则拒绝的请求", - "ip_activity_token_usage": "IP 活跃度 & Token 消耗", - "hour": "时", - "day": "日", - "week": "周", - "month": "月", - "rank": "排名", - "ip_address": "IP 地址", - "activity_reqs": "活跃度 (请求数)", - "total_token": "总 Token", - "prompt": "提问", - "completion": "回答", - "no_data": "暂无数据" + "total_requests": "鎬昏姹傛暟", + "total_requests_desc": "鎵€鏈夎褰曠殑璇锋眰", + "unique_ips": "鐙珛 IP 鏁?, + "unique_ips_desc": "涓嶅悓鐨勫鎴风 IP 鍦板潃", + "blocked_requests": "鎷︽埅璇锋眰鏁?, + "blocked_requests_desc": "琚鍒欐嫆缁濈殑璇锋眰", + "ip_activity_token_usage": "IP 娲昏穬搴?& Token 娑堣€?, + "hour": "鏃?, + "day": "鏃?, + "week": "鍛?, + "month": "鏈?, + "rank": "鎺掑悕", + "ip_address": "IP 鍦板潃", + "activity_reqs": "娲昏穬搴?(璇锋眰鏁?", + "total_token": "鎬?Token", + "prompt": "鎻愰棶", + "completion": "鍥炵瓟", + "no_data": "鏆傛棤鏁版嵁" }, "logs": { - "search_placeholder": "搜索 IP, 路径, User Agent...", - "username": "用户", - "show_blocked_only": "仅显示被拦截", - "status": "状态", - "ip_address": "IP 地址", - "method": "方法", - "path": "路径", - "duration": "耗时", - "time": "时间", - "reason": "原因", - "blocked": "拦截", - "no_logs": "暂无日志", - "total_records": "共 {{total}} 条记录", - "prev_page": "上一页", - "next_page": "下一页", - "page_num": "第 {{page}} 页", - "per_page_suffix": "/页" + "search_placeholder": "鎼滅储 IP, 璺緞, User Agent...", + "username": "鐢ㄦ埛", + "show_blocked_only": "浠呮樉绀鸿鎷︽埅", + "status": "鐘舵€?, + "ip_address": "IP 鍦板潃", + "method": "鏂规硶", + "path": "璺緞", + "duration": "鑰楁椂", + "time": "鏃堕棿", + "reason": "鍘熷洜", + "blocked": "鎷︽埅", + "no_logs": "鏆傛棤鏃ュ織", + "total_records": "鍏?{{total}} 鏉¤褰?, + "prev_page": "涓婁竴椤?, + "next_page": "涓嬩竴椤?, + "page_num": "绗?{{page}} 椤?, + "per_page_suffix": "/椤? }, "blacklist": { - "add_ip": "添加 IP", - "search_placeholder": "搜索...", - "added_at": "添加时间", - "expires_at": "过期时间", - "no_data": "暂无黑名单数据", - "add_title": "添加到黑名单", - "ip_cidr_label": "IP 地址或 CIDR", - "ip_cidr_placeholder": "例如 192.168.1.1 或 10.0.0.0/24", - "reason_label": "原因 (可选)", - "reason_placeholder": "例如:恶意扫描", - "expires_label": "过期时间(小时,可选)", - "expires_placeholder": "留空则永久生效", - "cancel": "取消", - "confirm": "添加", - "add_btn": "添加", - "error_duplicate": "该 IP 已存在于黑名单中", - "error_invalid_ip": "无效的 IP 格式。请使用 IP 地址或 CIDR 表示法(例如 192.168.1.0/24)", - "error_add_failed": "添加失败" + "add_ip": "娣诲姞 IP", + "search_placeholder": "鎼滅储...", + "added_at": "娣诲姞鏃堕棿", + "expires_at": "杩囨湡鏃堕棿", + "no_data": "鏆傛棤榛戝悕鍗曟暟鎹?, + "add_title": "娣诲姞鍒伴粦鍚嶅崟", + "ip_cidr_label": "IP 鍦板潃鎴?CIDR", + "ip_cidr_placeholder": "渚嬪 192.168.1.1 鎴?10.0.0.0/24", + "reason_label": "鍘熷洜 (鍙€?", + "reason_placeholder": "渚嬪锛氭伓鎰忔壂鎻?, + "expires_label": "杩囨湡鏃堕棿锛堝皬鏃讹紝鍙€夛級", + "expires_placeholder": "鐣欑┖鍒欐案涔呯敓鏁?, + "cancel": "鍙栨秷", + "confirm": "娣诲姞", + "add_btn": "娣诲姞", + "error_duplicate": "璇?IP 宸插瓨鍦ㄤ簬榛戝悕鍗曚腑", + "error_invalid_ip": "鏃犳晥鐨?IP 鏍煎紡銆傝浣跨敤 IP 鍦板潃鎴?CIDR 琛ㄧず娉曪紙渚嬪 192.168.1.0/24锛?, + "error_add_failed": "娣诲姞澶辫触" }, "whitelist": { - "add_ip": "添加信任 IP", - "no_data": "暂无白名单数据", - "add_title": "添加到白名单", - "description_label": "备注 (可选)", - "description_placeholder": "例如:内部服务器", - "cancel": "取消", - "confirm": "添加", - "add_btn": "添加" + "add_ip": "娣诲姞淇′换 IP", + "no_data": "鏆傛棤鐧藉悕鍗曟暟鎹?, + "add_title": "娣诲姞鍒扮櫧鍚嶅崟", + "description_label": "澶囨敞 (鍙€?", + "description_placeholder": "渚嬪锛氬唴閮ㄦ湇鍔″櫒", + "cancel": "鍙栨秷", + "confirm": "娣诲姞", + "add_btn": "娣诲姞" }, "config": { - "title": "安全设置", - "save": "保存更改", - "saving": "保存中...", - "blacklist_title": "IP 黑名单", - "blacklist_desc": "管理被拦截的 IP 地址和规则。", - "enable_blacklist": "启用黑名单保护", - "block_msg_label": "自定义拦截消息", - "block_msg_desc": "返回给被拦截客户端的响应内容。", - "whitelist_title": "IP 白名单", - "whitelist_desc": "管理信任的 IP 地址。", - "enable_whitelist": "启用白名单模式", - "whitelist_warning": "警告: 启用白名单模式将拦截所有不在白名单中的 IP 请求。如果您通过代理访问,请务必小心不要将自己锁在外面。", - "whitelist_priority": "白名单优先 (覆盖黑名单)", - "whitelist_priority_desc": "启用后,白名单 IP 将被允许访问,即使它们匹配黑名单规则。", - "load_error": "加载配置失败", - "save_success": "配置已保存", - "save_error": "保存配置失败" + "title": "瀹夊叏璁剧疆", + "save": "淇濆瓨鏇存敼", + "saving": "淇濆瓨涓?..", + "blacklist_title": "IP 榛戝悕鍗?, + "blacklist_desc": "绠$悊琚嫤鎴殑 IP 鍦板潃鍜岃鍒欍€?, + "enable_blacklist": "鍚敤榛戝悕鍗曚繚鎶?, + "block_msg_label": "鑷畾涔夋嫤鎴秷鎭?, + "block_msg_desc": "杩斿洖缁欒鎷︽埅瀹㈡埛绔殑鍝嶅簲鍐呭銆?, + "whitelist_title": "IP 鐧藉悕鍗?, + "whitelist_desc": "绠$悊淇′换鐨?IP 鍦板潃銆?, + "enable_whitelist": "鍚敤鐧藉悕鍗曟ā寮?, + "whitelist_warning": "璀﹀憡: 鍚敤鐧藉悕鍗曟ā寮忓皢鎷︽埅鎵€鏈変笉鍦ㄧ櫧鍚嶅崟涓殑 IP 璇锋眰銆傚鏋滄偍閫氳繃浠g悊璁块棶锛岃鍔″繀灏忓績涓嶈灏嗚嚜宸遍攣鍦ㄥ闈€?, + "whitelist_priority": "鐧藉悕鍗曚紭鍏?(瑕嗙洊榛戝悕鍗?", + "whitelist_priority_desc": "鍚敤鍚庯紝鐧藉悕鍗?IP 灏嗚鍏佽璁块棶锛屽嵆浣垮畠浠尮閰嶉粦鍚嶅崟瑙勫垯銆?, + "load_error": "鍔犺浇閰嶇疆澶辫触", + "save_success": "閰嶇疆宸蹭繚瀛?, + "save_error": "淇濆瓨閰嶇疆澶辫触" } }, "user_token": { - "title": "用户 Token 管理", - "total_users": "用户总数", - "active_tokens": "活跃 Token", - "total_created": "累计创建", - "create": "创建 Token", - "username": "用户名", + "title": "鐢ㄦ埛 Token 绠$悊", + "total_users": "鐢ㄦ埛鎬绘暟", + "active_tokens": "娲昏穬 Token", + "total_created": "绱鍒涘缓", + "create": "鍒涘缓 Token", + "username": "鐢ㄦ埛鍚?, "token": "Token", - "expires": "过期时间", - "usage": "使用量", - "ip_limit": "IP 限制", - "created": "创建时间", - "today_requests": "今日请求数", - "never": "永不过期", - "renew": "续期", - "renew_button": "续费", - "unlimited": "不限", - "create_title": "创建新 Token", - "description": "描述", - "curfew": "宵禁时间 (服务不可用时段)", - "edit_title": "编辑 Token", - "username_required": "用户名不能为空", - "renew_success": "续期成功", - "expires_day": "1 天", - "expires_week": "1 周", - "expires_month": "1 个月", - "expires_never": "永不过期", - "no_data": "暂无数据", - "placeholder_username": "例如: user1", - "placeholder_desc": "选填备注", - "placeholder_max_ips": "0 = 不限制", - "hint_max_ips": "0 表示不限制", - "hint_curfew": "留空则禁用。基于服务器时间。" + "expires": "杩囨湡鏃堕棿", + "usage": "浣跨敤閲?, + "ip_limit": "IP 闄愬埗", + "created": "鍒涘缓鏃堕棿", + "today_requests": "浠婃棩璇锋眰鏁?, + "never": "姘镐笉杩囨湡", + "renew": "缁湡", + "renew_button": "缁垂", + "unlimited": "涓嶉檺", + "create_title": "鍒涘缓鏂?Token", + "description": "鎻忚堪", + "curfew": "瀹电鏃堕棿 (鏈嶅姟涓嶅彲鐢ㄦ椂娈?", + "edit_title": "缂栬緫 Token", + "username_required": "鐢ㄦ埛鍚嶄笉鑳戒负绌?, + "renew_success": "缁湡鎴愬姛", + "expires_day": "1 澶?, + "expires_week": "1 鍛?, + "expires_month": "1 涓湀", + "expires_never": "姘镐笉杩囨湡", + "no_data": "鏆傛棤鏁版嵁", + "placeholder_username": "渚嬪: user1", + "placeholder_desc": "閫夊~澶囨敞", + "placeholder_max_ips": "0 = 涓嶉檺鍒?, + "hint_max_ips": "0 琛ㄧず涓嶉檺鍒?, + "hint_curfew": "鐣欑┖鍒欑鐢ㄣ€傚熀浜庢湇鍔″櫒鏃堕棿銆? } -} \ No newline at end of file +} diff --git a/src/stores/useAccountStore.ts b/src/stores/useAccountStore.ts index 26580e019..b9b36ee44 100644 --- a/src/stores/useAccountStore.ts +++ b/src/stores/useAccountStore.ts @@ -107,7 +107,16 @@ export const useAccountStore = create((set, get) => ({ set({ loading: true, error: null }); try { await accountService.switchAccount(accountId, targetIde); - await get().fetchCurrentAccount(); + await Promise.all([ + get().fetchCurrentAccount(), + get().fetchAccounts() + ]); + + // Asynchronously refresh quota to update the dashboard, do not block the UI + get().refreshQuota(accountId).catch(e => { + console.error('[Store] Background quota refresh failed after switch:', e); + }); + set({ loading: false }); } catch (error) { set({ error: String(error), loading: false }); @@ -120,6 +129,12 @@ export const useAccountStore = create((set, get) => ({ try { await accountService.fetchAccountQuota(accountId); await get().fetchAccounts(); + + const { currentAccount } = get(); + if (currentAccount && currentAccount.id === accountId) { + await get().fetchCurrentAccount(); + } + set({ loading: false }); } catch (error) { set({ error: String(error), loading: false }); From c17a7a6f010c3e20be8c7d8a86c5cf1e4382e456 Mon Sep 17 00:00:00 2001 From: Vucius Date: Fri, 12 Jun 2026 20:48:24 +0900 Subject: [PATCH 2/8] fix(locales): restore utf-8 encoding and fix TS1002 string literal errors --- src/locales/ar.json | 2 +- src/locales/en.json | 46 +- src/locales/es.json | 2 +- src/locales/ja.json | 2 +- src/locales/ko.json | 2 +- src/locales/my.json | 2 +- src/locales/pt.json | 2 +- src/locales/ru.json | 2 +- src/locales/tr.json | 2 +- src/locales/vi.json | 2 +- src/locales/zh-TW.json | 2 +- src/locales/zh.json | 2206 ++++++++++++++++++++-------------------- 12 files changed, 1136 insertions(+), 1136 deletions(-) diff --git a/src/locales/ar.json b/src/locales/ar.json index 5d3e050fa..3e033276a 100644 --- a/src/locales/ar.json +++ b/src/locales/ar.json @@ -1186,4 +1186,4 @@ "hint_max_ips": "0 = غير محدود", "hint_curfew": "اتركه فارغًا لتعطيله. بناءً على وقت الخادم." } -} +} \ No newline at end of file diff --git a/src/locales/en.json b/src/locales/en.json index 446abcda8..0186c4d3d 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1,4 +1,4 @@ -{ +{ "common": { "loading": "Loading...", "empty": "Empty", @@ -86,7 +86,7 @@ "logout": "Logout" }, "dashboard": { - "hello": "Hello, User 馃憢", + "hello": "Hello, User 👋", "refresh_quota": "Refresh Quota", "refreshing": "Refreshing...", "total_accounts": "Total Accounts", @@ -174,15 +174,15 @@ "validation_url_copied": "Verification link copied to clipboard", "fix_guide": { "title": "Terminal Quick Fix (Resolves internal 403s)", - "step1_title": "馃殌 Quickest Solution", + "step1_title": "🚀 Quickest Solution", "step1_desc": "Open your Terminal and run the following command to tell Google \"it's me\", which resolves most 403 blocks:", "step1_li1": "Press Enter, input <1>Y when prompted to continue.", "step1_li2": "Your browser will open automatically, select your account and click \"Allow\".", "step1_li3": "Once you see <1>You are now authenticated, you're all set!", - "step2_title": "馃Ч If that fails (Clear Cache)", + "step2_title": "🧹 If that fails (Clear Cache)", "step2_li1_prefix": "Run this to clear your old credentials:", "step2_li2_prefix": "Then log in again:", - "tips_title": "馃挕 Common Tips", + "tips_title": "💡 Common Tips", "tip1": "If you still get 403, try running <1>unset GOOGLE_APPLICATION_CREDENTIALS in terminal first.", "tip2": "For production environments, using a <1>Service Account JSON key is highly recommended for stability and headless operation.", "tip3": "If it still fails, check the Generative Language API in <1>Google Cloud Console to see if permissions are frozen. If so, your account is under risk control. Please let the account cool down for 72 hours before trying again.", @@ -388,7 +388,7 @@ "monitored_models_label": "Monitored Models (Trigger Conditions)", "monitored_models_desc": "Select at least one. Protection triggers if ANY selected model falls below threshold", "range": "Range", - "example": "Example: At {{percentage}}%, an account with {{total}} quota will be disabled when remaining 鈮?{{threshold}}", + "example": "Example: At {{percentage}}%, an account with {{total}} quota will be disabled when remaining ≤ {{threshold}}", "auto_restore_info": "Account will be automatically re-enabled when quota resets" }, "pinned_quota_models": { @@ -508,7 +508,7 @@ "http_api_port_placeholder": "Default port 19527", "http_api_port_invalid": "Invalid port number (range: 1024-65535)", "http_api_settings_saved": "HTTP API settings saved, restart required to apply", - "http_api_restart_required": "鈿狅笍 Restart required to apply" + "http_api_restart_required": "⚠️ Restart required to apply" }, "debug": { "title": "Debug Console", @@ -539,7 +539,7 @@ "telegram": "Telegram Channel", "github": "GitHub", "view_code": "View Code", - "copyright": "Copyright 漏 2025-2026 Antigravity. All rights reserved.", + "copyright": "Copyright © 2025-2026 Antigravity. All rights reserved.", "check_update": "Check for Updates", "checking_update": "Checking...", "latest_version": "You're up to date", @@ -658,10 +658,10 @@ "auto_start_tooltip": "Automatically starts the local API Proxy service when the app launches.", "allow_lan_access": "Allow LAN Access", "allow_lan_access_tooltip": "When enabled, the service binds to 0.0.0.0 so other devices on your LAN can access it. Keep authorization enabled and protect your API key; restart required to apply.", - "allow_lan_access_hint_enabled": "馃寪 Listening on 0.0.0.0, LAN devices can access", - "allow_lan_access_hint_disabled": "馃敀 Listening on 127.0.0.1 only, localhost access (Privacy First)", - "allow_lan_access_warning": "鈿狅笍 LAN devices can access when enabled. Keep your API key secure", - "allow_lan_access_restart_hint": "鈩癸笍 Service restart required to apply changes", + "allow_lan_access_hint_enabled": "🌐 Listening on 0.0.0.0, LAN devices can access", + "allow_lan_access_hint_disabled": "🔒 Listening on 127.0.0.1 only, localhost access (Privacy First)", + "allow_lan_access_warning": "⚠️ LAN devices can access when enabled. Keep your API key secure", + "allow_lan_access_restart_hint": "ℹ️ Service restart required to apply changes", "api_key": "API Key", "api_key_tooltip": "Shared secret used by clients when proxy authorization is enabled. Regenerating the key immediately invalidates the old one.", "btn_regenerate": "Regenerate Key", @@ -716,11 +716,11 @@ "hint": "Available models: {{count}}. Select a suggestion or type a custom model id.", "error": "Failed to fetch models: {{error}}", "select_placeholder": "Select model...", - "opus": "Opus family 鈫?z.ai model", + "opus": "Opus family → z.ai model", "opus_tooltip": "Default z.ai model id used when the incoming model contains \"opus\" (e.g. claude-opus-*).", - "sonnet": "Sonnet family 鈫?z.ai model", + "sonnet": "Sonnet family → z.ai model", "sonnet_tooltip": "Default z.ai model id used for other Claude models (e.g. claude-sonnet-* and most claude-* requests).", - "haiku": "Haiku family 鈫?z.ai model", + "haiku": "Haiku family → z.ai model", "haiku_tooltip": "Default z.ai model id used when the incoming model contains \"haiku\" (e.g. claude-haiku-*).", "advanced_title": "Advanced overrides", "advanced_tooltip": "Optional exact-match overrides. If an incoming model string matches a rule key, it will be replaced with the mapped z.ai model id.", @@ -987,7 +987,7 @@ "apply_presets": "Apply Presets", "presets_applied": "Presets applied successfully", "preset_default": "Default Preset", - "preset_default_desc": "GPT-4 鈫?Gemini Pro, Claude 鈫?Opus", + "preset_default_desc": "GPT-4 → Gemini Pro, Claude → Opus", "preset_performance": "Performance First", "preset_performance_desc": "Use high-performance models for all", "preset_cost": "Cost Optimized", @@ -1041,12 +1041,12 @@ }, "expert_title": "Expert Custom Routing", "expert_subtitle": "Precise matching for any original model ID.", - "custom_mapping_tip": "馃挕 Supports manual input of any model ID to experience unreleased models (e.g. claude-opus-4-6).", + "custom_mapping_tip": "💡 Supports manual input of any model ID to experience unreleased models (e.g. claude-opus-4-6).", "custom_mapping_warning": "Note: Not all accounts support unreleased models.", - "money_saving_tip": "馃挵 Cost-saving tip:", + "money_saving_tip": "💰 Cost-saving tip:", "haiku_optimization_tip": "Claude CLI uses {{model}} for background tasks by default. Map it to a cheaper Flash model to save ~95% costs", "haiku_optimization_btn": "Quick Optimize", - "haiku_tip_title": "馃挵 Cost-saving tip:", + "haiku_tip_title": "💰 Cost-saving tip:", "haiku_tip_body_before": "Claude CLI defaults to", "haiku_tip_body_after": "for background tasks; mapping it to a cheaper Flash model can save about 95% of the cost.", "haiku_tip_action": "Optimize", @@ -1055,7 +1055,7 @@ "add_mapping": "Add Mapping", "current_list": "Custom List", "no_custom_mapping": "No custom mappings yet", - "gemini3_only_warning": "鈿狅笍 Gemini 3 series only", + "gemini3_only_warning": "⚠️ Gemini 3 series only", "default_suffix": " (Default)", "original_id": "Original ID", "route_to": "Route To", @@ -1073,7 +1073,7 @@ "gemini_label": "Gemini Protocol", "gemini_tools": "Google AI SDK, LangChain", "quick_integration": "Quick Integration", - "click_tip": "馃憜 Click a model to update code examples", + "click_tip": "👆 Click a model to update code examples", "copy_base": "Copy Base" }, "supported_models": { @@ -1111,7 +1111,7 @@ "sync_error": "Sync failed: {{error}}" }, "sync_confirm_title": "Sync Confirmation", - "sync_confirm_message": "Ready to sync {{name}} configuration. 鈿狅笍 Warning: This will overwrite your existing local configuration files (e.g. login tokens, API Keys). Are you sure you want to continue?" + "sync_confirm_message": "Ready to sync {{name}} configuration. ⚠️ Warning: This will overwrite your existing local configuration files (e.g. login tokens, API Keys). Are you sure you want to continue?" } }, "monitor": { @@ -1391,4 +1391,4 @@ "hint_max_ips": "0 = Unlimited", "hint_curfew": "Leave empty to disable. Based on server time." } -} +} \ No newline at end of file diff --git a/src/locales/es.json b/src/locales/es.json index 8067e40fd..7ba644896 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -1084,4 +1084,4 @@ "hint_max_ips": "0 significa ilimitado", "hint_curfew": "Dejar vacío para desactivar. Basado en la hora del servidor." } -} +} \ No newline at end of file diff --git a/src/locales/ja.json b/src/locales/ja.json index d0395ffa8..536b93b94 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1334,4 +1334,4 @@ "hint_max_ips": "0 は制限なしを意味します", "hint_curfew": "空欄で無効。サーバー時間に基づきます。" } -} +} \ No newline at end of file diff --git a/src/locales/ko.json b/src/locales/ko.json index 2c1352947..8d5ef5acf 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1216,4 +1216,4 @@ "hint_max_ips": "0 = 무제한", "hint_curfew": "비워두면 비활성화됩니다. 서버 시간 기준." } -} +} \ No newline at end of file diff --git a/src/locales/my.json b/src/locales/my.json index 50a5e2a39..a73013748 100644 --- a/src/locales/my.json +++ b/src/locales/my.json @@ -1084,4 +1084,4 @@ "hint_max_ips": "0 bermaksud tanpa had", "hint_curfew": "Biarkan kosong untuk nyahaktifkan. Berdasarkan masa pelayan." } -} +} \ No newline at end of file diff --git a/src/locales/pt.json b/src/locales/pt.json index f9c7f0bea..d4b33fb6e 100644 --- a/src/locales/pt.json +++ b/src/locales/pt.json @@ -1178,4 +1178,4 @@ "hint_max_ips": "0 significa ilimitado", "hint_curfew": "Deixe em branco para desativar. Baseado na hora do servidor." } -} +} \ No newline at end of file diff --git a/src/locales/ru.json b/src/locales/ru.json index 4a751c415..f8fbf02f0 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -1173,4 +1173,4 @@ "hint_max_ips": "0 означает безлимитно", "hint_curfew": "Оставьте пустым, чтобы отключить. По времени сервера." } -} +} \ No newline at end of file diff --git a/src/locales/tr.json b/src/locales/tr.json index a0a154f9e..c1d2398a3 100644 --- a/src/locales/tr.json +++ b/src/locales/tr.json @@ -1147,4 +1147,4 @@ "hint_max_ips": "0 sınırsız demektir", "hint_curfew": "Devre dışı bırakmak için boş bırakın. Sunucu saatine göredir." } -} +} \ No newline at end of file diff --git a/src/locales/vi.json b/src/locales/vi.json index 3511f2bb0..d5aff3ecd 100644 --- a/src/locales/vi.json +++ b/src/locales/vi.json @@ -1196,4 +1196,4 @@ "hint_max_ips": "0 nghĩa là không giới hạn", "hint_curfew": "Để trống để tắt. Dựa trên giờ máy chủ." } -} +} \ No newline at end of file diff --git a/src/locales/zh-TW.json b/src/locales/zh-TW.json index 3fda25b57..1a59aa0e2 100644 --- a/src/locales/zh-TW.json +++ b/src/locales/zh-TW.json @@ -1207,4 +1207,4 @@ "hint_max_ips": "0 表示不限制", "hint_curfew": "留空則禁用。基於伺服器時間。" } -} +} \ No newline at end of file diff --git a/src/locales/zh.json b/src/locales/zh.json index fefec5a40..f781eb752 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -1,1359 +1,1359 @@ -{ +{ "common": { - "loading": "鍔犺浇涓?..", - "load_more": "鍔犺浇鏇村", - "add": "娣诲姞", - "copy": "澶嶅埗", - "action": "鎿嶄綔", - "save": "淇濆瓨", - "saved": "淇濆瓨鎴愬姛", - "cancel": "鍙栨秷", - "confirm": "纭", - "close": "鍏抽棴", - "delete": "鍒犻櫎", - "edit": "缂栬緫", - "refresh": "鍒锋柊", - "refreshing": "鍒锋柊涓?..", - "export": "瀵煎嚭", - "import": "瀵煎叆", - "success": "鎴愬姛", - "error": "閿欒", - "unknown": "鏈煡", - "warning": "璀﹀憡", - "info": "鎻愮ず", - "details": "璇︽儏", - "example": "绀轰緥", - "clear": "娓呴櫎", - "clearing": "娓呯悊涓?..", - "prev_page": "涓婁竴椤?, - "next_page": "涓嬩竴椤?, - "pagination_info": "鏄剧ず绗?{{start}} 鍒?{{end}} 鏉★紝鍏?{{total}} 鏉?, - "per_page": "姣忛〉", - "items": "鏉?, - "accounts": "涓处鍙?, - "enabled": "宸插惎鐢?, - "disabled": "宸茬鐢?, - "tauri_api_not_loaded": "Tauri API 鏈纭姞杞?璇烽噸鍚簲鐢?, - "environment_error": "鐜閿欒: {{error}}", - "submit": "鎻愪氦", - "update": "鏇存柊", - "load_failed": "鍔犺浇澶辫触", - "create_success": "鍒涘缓鎴愬姛", - "update_success": "鏇存柊鎴愬姛", - "delete_success": "鍒犻櫎鎴愬姛", - "copied": "宸插鍒跺埌鍓创鏉?, - "reason": "鍘熷洜", - "show_raw": "鏄剧ず鍘熷鎶ユ枃", - "show_parsed": "鏄剧ず瑙f瀽鍚? + "loading": "加载中...", + "load_more": "加载更多", + "add": "添加", + "copy": "复制", + "action": "操作", + "save": "保存", + "saved": "保存成功", + "cancel": "取消", + "confirm": "确认", + "close": "关闭", + "delete": "删除", + "edit": "编辑", + "refresh": "刷新", + "refreshing": "刷新中...", + "export": "导出", + "import": "导入", + "success": "成功", + "error": "错误", + "unknown": "未知", + "warning": "警告", + "info": "提示", + "details": "详情", + "example": "示例", + "clear": "清除", + "clearing": "清理中...", + "prev_page": "上一页", + "next_page": "下一页", + "pagination_info": "显示第 {{start}} 到 {{end}} 条,共 {{total}} 条", + "per_page": "每页", + "items": "条", + "accounts": "个账号", + "enabled": "已启用", + "disabled": "已禁用", + "tauri_api_not_loaded": "Tauri API 未正确加载,请重启应用", + "environment_error": "环境错误: {{error}}", + "submit": "提交", + "update": "更新", + "load_failed": "加载失败", + "create_success": "创建成功", + "update_success": "更新成功", + "delete_success": "删除成功", + "copied": "已复制到剪贴板", + "reason": "原因", + "show_raw": "显示原始报文", + "show_parsed": "显示解析后" }, "nav": { - "dashboard": "浠〃鐩?, - "accounts": "璐﹀彿绠$悊", - "proxy": "API 鍙嶄唬", - "call_records": "娴侀噺鏃ュ織", - "token_stats": "Token 缁熻", - "security": "IP 绠$悊", - "security_logs": "IP 鏃ュ織", - "settings": "璁剧疆", - "theme_to_dark": "鍒囨崲鍒版繁鑹叉ā寮?, - "theme_to_light": "鍒囨崲鍒版祬鑹叉ā寮?, - "switch_to_english": "鍒囨崲鍒拌嫳鏂?, - "switch_to_chinese": "鍒囨崲鍒颁腑鏂?, - "switch_to_traditional_chinese": "鍒囨崲鍒扮箒浣撲腑鏂?, + "dashboard": "仪表盘", + "accounts": "账号管理", + "proxy": "API 反代", + "call_records": "流量日志", + "token_stats": "Token 统计", + "security": "IP 管理", + "security_logs": "IP 日志", + "settings": "设置", + "theme_to_dark": "切换到深色模式", + "theme_to_light": "切换到浅色模式", + "switch_to_english": "切换到英文", + "switch_to_chinese": "切换到中文", + "switch_to_traditional_chinese": "切换到繁体中文", "switch_to_english_short": "EN", "switch_to_chinese_short": "ZH", "switch_to_traditional_chinese_short": "TW", - "switch_to_japanese": "鍒囨崲鍒版棩鏂?, + "switch_to_japanese": "切换到日文", "switch_to_japanese_short": "JA", - "switch_to_turkish": "鍒囨崲鍒板湡鑰冲叾鏂?, + "switch_to_turkish": "切换到土耳其文", "switch_to_turkish_short": "TR", - "switch_to_vietnamese": "鍒囨崲鍒拌秺鍗楁枃", + "switch_to_vietnamese": "切换到越南文", "switch_to_vietnamese_short": "VI", - "switch_to_russian": "鍒囨崲鍒颁縿鏂?, + "switch_to_russian": "切换到俄文", "switch_to_russian_short": "RU", - "switch_to_portuguese": "鍒囨崲鍒拌憽钀勭墮鏂?, + "switch_to_portuguese": "切换到葡萄牙文", "switch_to_portuguese_short": "PT", - "switch_to_korean": "鍒囨崲鍒伴煩璇?, + "switch_to_korean": "切换到韩语", "switch_to_korean_short": "KO", - "switch_to_spanish": "鍒囨崲鍒拌タ鐝墮璇?, + "switch_to_spanish": "切换到西班牙语", "switch_to_spanish_short": "ES", - "switch_to_malay": "鍒囨崲鍒伴┈鏉ヨ", + "switch_to_malay": "切换到马来语", "switch_to_malay_short": "MY", - "user_token": "鐢ㄦ埛 Token", - "logout": "鐧诲嚭" + "user_token": "用户 Token", + "logout": "登出" }, "dashboard": { - "hello": "浣犲ソ, 鐢ㄦ埛 馃憢", - "refresh_quota": "鍒锋柊閰嶉", - "refreshing": "鍒锋柊涓?..", - "total_accounts": "鎬昏处鍙锋暟", - "avg_gemini": "Gemini 骞冲潎閰嶉", - "avg_gemini_image": "Gemini 缁樺浘骞冲潎閰嶉", - "avg_claude": "Claude 骞冲潎閰嶉", - "low_quota_accounts": "浣庨厤棰濊处鍙?, - "quota_sufficient": "鉁?閰嶉鍏呰冻", - "quota_low": "鈿?閰嶉杈冧綆", - "quota_desc": "閰嶉 < 20%", - "current_account": "褰撳墠璐﹀彿", - "switch_account": "鍒囨崲璐﹀彿", - "no_active_account": "鏆傛棤娲昏穬璐﹀彿", - "best_accounts": "鏈€浣宠处鍙锋帹鑽?, - "best_account_recommendation": "鏈€浣宠处鍙锋帹鑽?, - "switch_best": "涓€閿垏鎹㈡渶浣?, - "switch_successfully": "涓€閿垏鎹㈡渶浣?, - "view_all_accounts": "鏌ョ湅鎵€鏈夎处鍙?, - "export_data": "瀵煎嚭璐﹀彿鏁版嵁", - "for_gemini": "鐢ㄤ簬 Gemini", - "for_claude": "鐢ㄤ簬 Claude", + "hello": "你好, 用户 👋", + "refresh_quota": "刷新配额", + "refreshing": "刷新中...", + "total_accounts": "总账号数", + "avg_gemini": "Gemini 平均配额", + "avg_gemini_image": "Gemini 绘图平均配额", + "avg_claude": "Claude 平均配额", + "low_quota_accounts": "低配额账号", + "quota_sufficient": "✓ 配额充足", + "quota_low": "⚠ 配额较低", + "quota_desc": "配额 < 20%", + "current_account": "当前账号", + "switch_account": "切换账号", + "no_active_account": "暂无活跃账号", + "best_accounts": "最佳账号推荐", + "best_account_recommendation": "最佳账号推荐", + "switch_best": "一键切换最佳", + "switch_successfully": "一键切换最佳", + "view_all_accounts": "查看所有账号", + "export_data": "导出账号数据", + "for_gemini": "用于 Gemini", + "for_claude": "用于 Claude", "toast": { - "switch_success": "鍒囨崲鎴愬姛!", - "switch_error": "鍒囨崲璐﹀彿澶辫触", - "refresh_success": "閰嶉鍒锋柊鎴愬姛", - "refresh_error": "鍒锋柊澶辫触", - "export_no_accounts": "娌℃湁鍙鍑虹殑璐﹀彿", - "export_success": "瀵煎嚭鎴愬姛! 鏂囦欢宸蹭繚瀛樿嚦: {{path}}", - "export_error": "瀵煎嚭澶辫触" + "switch_success": "切换成功!", + "switch_error": "切换账号失败", + "refresh_success": "配额刷新成功", + "refresh_error": "刷新失败", + "export_no_accounts": "没有可导出的账号", + "export_success": "导出成功! 文件已保存至: {{path}}", + "export_error": "导出失败" } }, "accounts": { - "account": "璐﹀彿", - "search_placeholder": "鎼滅储閭...", - "all": "鍏ㄩ儴", - "available": "鍙敤", - "low_quota": "浣庨厤棰?, + "account": "账号", + "search_placeholder": "搜索邮箱...", + "all": "全部", + "available": "可用", + "low_quota": "低配额", "ultra": "ULTRA", "pro": "PRO", "free": "FREE", - "edit_label": "缂栬緫鏍囩", - "custom_label_placeholder": "杈撳叆鑷畾涔夋爣绛?, - "label_updated": "鏍囩宸叉洿鏂?, - "add_account": "娣诲姞璐﹀彿", - "refresh_all": "鍒锋柊鎵€鏈?, - "refresh_selected": "鍒锋柊 ({{count}})", - "export_selected": "瀵煎嚭 ({{count}})", - "import_json": "瀵煎叆", - "import_success": "鎴愬姛瀵煎叆 {{count}} 涓处鍙?, - "import_partial": "瀵煎叆瀹屾垚: {{success}} 涓垚鍔? {{fail}} 涓け璐?, - "import_fail": "瀵煎叆澶辫触: {{error}}", - "import_invalid_format": "鏃犳晥鐨?JSON 鏍煎紡锛岃纭繚鏂囦欢鍖呭惈 email 鍜?refresh_token 瀛楁", - "delete_selected": "鍒犻櫎 ({{count}})", - "current": "褰撳墠", - "current_badge": "褰撳墠", - "disabled": "宸茬鐢?, - "disabled_tooltip": "璐﹀彿宸茶绂佺敤锛堜緥濡?refresh_token 琚挙閿€/杩囨湡锛夈€傞噸鏂版巿鏉冩垨鏇存柊 Token 鍚庡彲鎭㈠銆?, - "proxy_disabled": "鍙嶄唬宸茬鐢?, - "proxy_disabled_tooltip": "姝よ处鍙峰凡琚墜鍔ㄧ鐢ㄥ弽浠e姛鑳?涓嶅弬涓?API 璇锋眰,浣嗕粛鍙湪搴旂敤涓娇鐢?, - "enable_proxy": "鍚敤鍙嶄唬", - "disable_proxy": "绂佺敤鍙嶄唬", - "enable_proxy_selected": "鍚敤 ({{count}})", - "disable_proxy_selected": "绂佺敤 ({{count}})", - "proxy_disabled_reason_manual": "鐢ㄦ埛鎵嬪姩绂佺敤", - "proxy_disabled_reason_batch": "鎵归噺绂佺敤", + "edit_label": "编辑标签", + "custom_label_placeholder": "输入自定义标签", + "label_updated": "标签已更新", + "add_account": "添加账号", + "refresh_all": "刷新所有", + "refresh_selected": "刷新 ({{count}})", + "export_selected": "导出 ({{count}})", + "import_json": "导入", + "import_success": "成功导入 {{count}} 个账号", + "import_partial": "导入完成: {{success}} 个成功, {{fail}} 个失败", + "import_fail": "导入失败: {{error}}", + "import_invalid_format": "无效的 JSON 格式,请确保文件包含 email 和 refresh_token 字段", + "delete_selected": "删除 ({{count}})", + "current": "当前", + "current_badge": "当前", + "disabled": "已禁用", + "disabled_tooltip": "账号已被禁用(例如 refresh_token 被撤销/过期)。重新授权或更新 Token 后可恢复。", + "proxy_disabled": "反代已禁用", + "proxy_disabled_tooltip": "此账号已被手动禁用反代功能,不参与 API 请求,但仍可在应用中使用", + "enable_proxy": "启用反代", + "disable_proxy": "禁用反代", + "enable_proxy_selected": "启用 ({{count}})", + "disable_proxy_selected": "禁用 ({{count}})", + "proxy_disabled_reason_manual": "用户手动禁用", + "proxy_disabled_reason_batch": "批量禁用", "forbidden": "403", "forbidden_badge": "403", - "forbidden_tooltip": "API 杩斿洖 403 Forbidden锛岃处鍙锋棤鏉冧娇鐢?Gemini Code Assist", - "forbidden_msg": "璐﹀彿鏃犳潈闄愶紝宸茶烦杩囪嚜鍔ㄥ埛鏂?, + "forbidden_tooltip": "API 返回 403 Forbidden,账号无权使用 Gemini Code Assist", + "forbidden_msg": "账号无权限,已跳过自动刷新", "status": { "forbidden": "403 Forbidden", - "disabled": "璐﹀彿宸茬鐢?, - "proxy_disabled": "鍙嶄唬宸茬鐢?, - "validation_required": "璐﹀彿闇€楠岃瘉", - "risk_controlled": "椋庢帶/闄愭祦", - "oauth_reauth_required": "鎺堟潈寮傚父", - "violation_blocked": "鐢变簬杩濊琚鐢? + "disabled": "账号已禁用", + "proxy_disabled": "反代已禁用", + "validation_required": "账号需验证", + "risk_controlled": "风控/限流", + "oauth_reauth_required": "授权异常", + "violation_blocked": "由于违规被禁用" }, - "error_details": "閿欒璇︽儏", - "error_status": "閿欒鐘舵€?, - "error_time": "妫€娴嬫椂闂?, - "view_error": "鏌ョ湅鍘熷洜", - "click_to_verify": "鐐瑰嚮鍘婚獙璇?, - "copy_validation_url": "澶嶅埗楠岃瘉閾炬帴", - "validation_url_copied": "楠岃瘉閾炬帴宸插鍒跺埌鍓创鏉?, - "go_to_appeal": "鍓嶅線鐢宠瘔", - "copy_appeal_url": "澶嶅埗鐢宠瘔閾炬帴", + "error_details": "错误详情", + "error_status": "错误状态", + "error_time": "检测时间", + "view_error": "查看原因", + "click_to_verify": "点击去验证", + "copy_validation_url": "复制验证链接", + "validation_url_copied": "验证链接已复制到剪贴板", + "go_to_appeal": "前往申诉", + "copy_appeal_url": "复制申诉链接", "fix_guide": { - "title": "缁堢涓€閿嚜鏁戞寚鍗?(瑙e喅閮ㄥ垎 403 鎷︽埅)", - "step1_title": "馃殌 缁堟瀬鏉€鎷涳紙鏈€蹇柟妗堬級", - "step1_desc": "鎵撳紑缁堢锛圱erminal锛夛紝鎵ц浠ヤ笅鍛戒护鍛婅瘔 Google \"鏄垜鏈汉\"锛屽彲瑙e喅閮ㄥ垎 403 鎷︽埅锛?, - "step1_li1": "鎸夊洖杞︽墽琛岋紝鎻愮ず缁х画鏃惰緭鍏?<1>Y銆?, - "step1_li2": "娴忚鍣ㄨ嚜鍔ㄦ墦寮€锛岄€夋嫨璐﹀彿骞垛€滃厑璁糕€濄€?, - "step1_li3": "鐪嬪埌 <1>You are now authenticated 鍗冲ぇ鍔熷憡鎴愶紒", - "step2_title": "馃Ч 濡傛灉鏃犳晥锛堟竻闄ょ紦瀛橀噸鏉ワ級", - "step2_li1_prefix": "鍏堟墽琛屾竻闄ゅ懡浠ら€€鍑烘棫璁よ瘉锛?, - "step2_li2_prefix": "鍐嶆墽琛岀櫥褰曪細", - "tips_title": "馃挕 甯歌寤鸿", - "tip1": "鑻ヤ粛 403锛屽皾璇曞厛鍦ㄧ粓绔墽琛?<1>unset GOOGLE_APPLICATION_CREDENTIALS 閲嶇疆鐜鍙橀噺銆?, - "tip2": "鐢熶骇鐜寮虹儓寤鸿鏀圭敤 <1>鏈嶅姟璐︽埛 (Service Account) 鐨?JSON 瀵嗛挜锛屾洿绋冲畾涓斿厤浜や簰銆?, - "tip3": "鑻ユ搷浣滃け璐ワ紝璇峰墠寰€ <1>Google Cloud Console 涓殑 Generative Language API 鏌ョ湅鏄惁琚喕缁撴潈闄愩€傝嫢鏄紝璇存槑璐﹀彿瑙﹀彂浜嗛鎺э紝寤鸿璁╄处鍙峰喎鍗?72 灏忔椂鍚庡啀娆″皾璇曘€?, - "tip4": "浣犱篃鍙互灏濊瘯鎵ц <1>npm install -g @google/gemini-cli锛屽彧瑕佷笉寮瑰嚭閿欒锛屽ぇ姒傜巼鍦ㄨ蒋浠跺唴鍒犻櫎璐﹀彿閲嶆柊鎺堟潈鍗冲彲銆? + "title": "终端一键自救指南 (解决部分 403 拦截)", + "step1_title": "🚀 终极杀招(最快方案)", + "step1_desc": "打开终端(Terminal),执行以下命令告诉 Google \"是我本人\",可解决部分 403 拦截:", + "step1_li1": "按回车执行,提示继续时输入 <1>Y。", + "step1_li2": "浏览器自动打开,选择账号并“允许”。", + "step1_li3": "看到 <1>You are now authenticated 即大功告成!", + "step2_title": "🧹 如果无效(清除缓存重来)", + "step2_li1_prefix": "先执行清除命令退出旧认证:", + "step2_li2_prefix": "再执行登录:", + "tips_title": "💡 常见建议", + "tip1": "若仍 403,尝试先在终端执行 <1>unset GOOGLE_APPLICATION_CREDENTIALS 重置环境变量。", + "tip2": "生产环境强烈建议改用 <1>服务账户 (Service Account) 的 JSON 密钥,更稳定且免交互。", + "tip3": "若操作失败,请前往 <1>Google Cloud Console 中的 Generative Language API 查看是否被冻结权限。若是,说明账号触发了风控,建议让账号冷却 72 小时后再次尝试。", + "tip4": "你也可以尝试执行 <1>npm install -g @google/gemini-cli,只要不弹出错误,大概率在软件内删除账号重新授权即可。" }, - "no_data": "鏃犳暟鎹?, - "last_used": "鏈€鍚庝娇鐢?, - "reset_time": "閲嶇疆鏃堕棿", - "switch_to": "鍒囨崲鍒版璐﹀彿", - "switch_to_classic": "鍒囨崲鍒?Antigravity (缁忓吀鐗?", - "switch_to_ide": "鍒囨崲鍒?Antigravity IDE", - "actions": "鎿嶄綔", - "device_fingerprint": "璁惧鎸囩汗", - "show_all_quotas": "鏄剧ず鎵€鏈夐厤棰?, + "no_data": "无数据", + "last_used": "最后使用", + "reset_time": "重置时间", + "switch_to": "切换到此账号", + "switch_to_classic": "切换到 Antigravity (经典版)", + "switch_to_ide": "切换到 Antigravity IDE", + "actions": "操作", + "device_fingerprint": "设备指纹", + "show_all_quotas": "显示所有配额", "device_fingerprint_dialog": { - "title": "璁惧鎸囩汗", - "operations": "璁惧鎸囩汗鎿嶄綔", - "generate_and_bind": "鐢熸垚骞剁粦瀹?, - "restore_original": "鎭㈠鍘熷", - "open_storage_directory": "鎵撳紑瀛樺偍鐩綍", - "current_storage": "褰撳墠瀛樺偍", - "effective": "宸茬敓鏁?, - "current_storage_desc": "璇诲彇鑷?storage.json锛堝垏鎹㈣处鍙锋椂搴旂敤缁戝畾鍚庢洿鏂帮級", - "account_binding": "璐﹀彿缁戝畾", - "pending_application": "寰呭簲鐢?, - "account_binding_desc": "鐢熸垚/鎭㈠鍚庝繚瀛樹负缁戝畾锛屽垏鎹㈣处鍙锋椂鍐欏叆 storage.json", - "historical_fingerprints": "鍘嗗彶鎸囩汗锛堝彲閫夋仮澶?鍒犻櫎锛?, - "no_history": "鏆傛棤鍘嗗彶", - "current": "褰撳墠", - "restore": "鎭㈠", - "delete_version": "鍒犻櫎姝ょ増鏈?, - "confirm_generate_title": "纭鐢熸垚骞剁粦瀹氾紵", - "confirm_generate_desc": "灏嗙敓鎴愪竴濂楁柊鐨勮澶囨寚绾瑰苟璁剧疆涓哄綋鍓嶆寚绾广€傜‘璁ょ户缁紵", - "confirm_restore_title": "纭鎭㈠鍘熷鎸囩汗锛?, - "confirm_restore_desc": "灏嗘仮澶嶄负鍘熷鎸囩汗骞惰鐩栧綋鍓嶆寚绾广€傜‘璁ょ户缁紵", - "cancel": "鍙栨秷", - "confirm": "纭", - "processing": "澶勭悊涓?..", - "loading": "鍔犺浇涓?..", - "failed_to_load_device_info": "鍔犺浇璁惧淇℃伅澶辫触", - "generation_failed": "鐢熸垚澶辫触", - "binding_failed": "缁戝畾澶辫触", - "restoration_failed": "鎭㈠澶辫触", - "deletion_failed": "鍒犻櫎澶辫触", - "directory_open_failed": "鏃犳硶鎵撳紑鐩綍", - "generated_and_bound": "宸茬敓鎴愬苟缁戝畾", - "restored": "宸叉仮澶?, - "deleted": "宸插垹闄?, - "directory_opened": "宸叉墦寮€璁惧瀛樺偍鐩綍", - "original_fingerprint_not_found": "鏈壘鍒板師濮嬫寚绾? + "title": "设备指纹", + "operations": "设备指纹操作", + "generate_and_bind": "生成并绑定", + "restore_original": "恢复原始", + "open_storage_directory": "打开存储目录", + "current_storage": "当前存储", + "effective": "已生效", + "current_storage_desc": "读取自 storage.json(切换账号时应用绑定后更新)", + "account_binding": "账号绑定", + "pending_application": "待应用", + "account_binding_desc": "生成/恢复后保存为绑定,切换账号时写入 storage.json", + "historical_fingerprints": "历史指纹(可选恢复/删除)", + "no_history": "暂无历史", + "current": "当前", + "restore": "恢复", + "delete_version": "删除此版本", + "confirm_generate_title": "确认生成并绑定?", + "confirm_generate_desc": "将生成一套新的设备指纹并设置为当前指纹。确认继续?", + "confirm_restore_title": "确认恢复原始指纹?", + "confirm_restore_desc": "将恢复为原始指纹并覆盖当前指纹。确认继续?", + "cancel": "取消", + "confirm": "确认", + "processing": "处理中...", + "loading": "加载中...", + "failed_to_load_device_info": "加载设备信息失败", + "generation_failed": "生成失败", + "binding_failed": "绑定失败", + "restoration_failed": "恢复失败", + "deletion_failed": "删除失败", + "directory_open_failed": "无法打开目录", + "generated_and_bound": "已生成并绑定", + "restored": "已恢复", + "deleted": "已删除", + "directory_opened": "已打开设备存储目录", + "original_fingerprint_not_found": "未找到原始指纹" }, - "warmup_all": "涓€閿鐑?, - "warmup_selected": "棰勭儹 ({{count}})", - "warmup_this": "棰勭儹璇ヨ处鍙?, - "warmup_now": "绔嬪嵆棰勭儹", - "warmup_batch_triggered": "宸叉垚鍔熶负 {{count}} 涓处鍙疯Е鍙戦鐑换鍔?, - "quota_protected": "鍙椾繚鎶?, + "warmup_all": "一键预热", + "warmup_selected": "预热 ({{count}})", + "warmup_this": "预热该账号", + "warmup_now": "立即预热", + "warmup_batch_triggered": "已成功为 {{count}} 个账号触发预热任务", + "quota_protected": "受保护", "details": { - "title": "閰嶉璇︽儏", - "model_quota": "妯″瀷閰嶉", - "protected_models": "鍙椾繚鎶ゆā鍨? + "title": "配额详情", + "model_quota": "模型配额", + "protected_models": "受保护模型" }, "toast": { - "proxy_enabled": "鎴愬姛鍚敤 {{count}} 涓处鍙风殑鍙嶄唬鍔熻兘", - "proxy_disabled": "鎴愬姛绂佺敤 {{count}} 涓处鍙风殑鍙嶄唬鍔熻兘" + "proxy_enabled": "成功启用 {{count}} 个账号的反代功能", + "proxy_disabled": "成功禁用 {{count}} 个账号的反代功能" }, "add": { - "title": "娣诲姞鏂拌处鍙?, + "title": "添加新账号", "tabs": { - "oauth": "OAuth 鎺堟潈", + "oauth": "OAuth 授权", "token": "Refresh Token", - "import": "浠庢暟鎹簱瀵煎叆" + "import": "从数据库导入" }, "oauth": { - "recommend": "鎺ㄨ崘鏂瑰紡", - "desc": "灏嗘墦寮€榛樿娴忚鍣ㄨ繘琛?Google 鐧诲綍鎺堟潈锛岃嚜鍔ㄨ幏鍙栧苟淇濆瓨 Token銆?, - "btn_start": "寮€濮?OAuth 鎺堟潈", - "btn_waiting": "姝e湪绛夊緟鎺堟潈...", - "btn_finish": "鎴戝凡鎺堟潈锛岀户缁?, - "copy_link": "澶嶅埗鎺堟潈閾炬帴", - "copied": "宸插鍒?, - "link_label": "鎺堟潈閾炬帴", - "link_click_to_copy": "鐐瑰嚮澶嶅埗", - "manual_hint": "娴忚鍣ㄦ病鏈夎嚜鍔ㄨ烦杞紵璇峰湪姝ゅ绮樿创鍥炶皟閾炬帴鎴?Authorization Code锛?, - "manual_placeholder": "绮樿创鍥炶皟閾炬帴鎴?Code...", - "error_no_flow": "璇峰厛鐐瑰嚮鈥滃紑濮?OAuth 鎺堟潈鈥?, - "web_hint": "灏嗗湪鏂扮獥鍙d腑鎵撳紑 Google 鐧诲綍椤?, - "error_no_url": "鏃犳硶鑾峰彇 OAuth URL", - "popup_blocked": "寮圭獥琚嫤鎴紝璇峰厑璁稿脊鍑虹獥鍙?, - "manual_submitting": "姝e湪鎻愪氦璁よ瘉鐮?..", - "manual_submitted": "璁よ瘉鐮佸凡鎻愪氦锛屽悗鍙板鐞嗕腑..." + "recommend": "推荐方式", + "desc": "将打开默认浏览器进行 Google 登录授权,自动获取并保存 Token。", + "btn_start": "开始 OAuth 授权", + "btn_waiting": "正在等待授权...", + "btn_finish": "我已授权,继续", + "copy_link": "复制授权链接", + "copied": "已复制", + "link_label": "授权链接", + "link_click_to_copy": "点击复制", + "manual_hint": "浏览器没有自动跳转?请在此处粘贴回调链接或 Authorization Code:", + "manual_placeholder": "粘贴回调链接或 Code...", + "error_no_flow": "请先点击“开始 OAuth 授权”", + "web_hint": "将在新窗口中打开 Google 登录页", + "error_no_url": "无法获取 OAuth URL", + "popup_blocked": "弹窗被拦截,请允许弹出窗口", + "manual_submitting": "正在提交认证码...", + "manual_submitted": "认证码已提交,后台处理中..." }, "token": { "label": "Refresh Token", - "placeholder": "鍦ㄦ澶勭矘璐存偍鐨?Refresh Token (鏀寔鎵归噺)\n\n鏀寔鏍煎紡:\n1. 鍗曚釜 Token (1//...)\n2. JSON 鏁扮粍 (鍚?refresh_token 瀛楁)\n3. 浠绘剰鍖呭惈 Token 鐨勬枃鏈?(鑷姩鎻愬彇)", - "hint": "鎻愮ず: 鏀寔涓€娆℃€х矘璐村涓?Token 鎴?JSON 鏁扮粍锛岀郴缁熷皢鑷姩璇嗗埆骞舵壒閲忓鍏ャ€?, - "error_token": "璇峰~鍐?Refresh Token", - "batch_progress": "姝e湪瀵煎叆绗?{{current}}/{{total}} 涓处鎴?..", - "batch_success": "鎴愬姛瀵煎叆 {{count}} 涓处鎴?, - "batch_partial": "瀵煎叆瀹屾垚: {{success}} 涓垚鍔? {{fail}} 涓け璐?, - "batch_fail": "瀵煎叆澶辫触" + "placeholder": "在此处粘贴您的 Refresh Token (支持批量)\n\n支持格式:\n1. 单个 Token (1//...)\n2. JSON 数组 (含 refresh_token 字段)\n3. 任意包含 Token 的文本 (自动提取)", + "hint": "提示: 支持一次性粘贴多个 Token 或 JSON 数组,系统将自动识别并批量导入。", + "error_token": "请填写 Refresh Token", + "batch_progress": "正在导入第 {{current}}/{{total}} 个账户...", + "batch_success": "成功导入 {{count}} 个账户", + "batch_partial": "导入完成: {{success}} 个成功, {{fail}} 个失败", + "batch_fail": "导入失败" }, "import": { - "scheme_a": "鏂规 A: 浠庡綋鍓?IDE 鏁版嵁搴?, - "scheme_a_desc": "鑷姩浠庢湰鍦?Antigravity 鏁版嵁搴撹鍙栧綋鍓嶇櫥褰曠殑璐﹀彿淇℃伅銆?, - "btn_db": "瀵煎叆褰撳墠鐧诲綍璐﹀彿", - "or": "鎴栬€?, - "scheme_b": "鏂规 B: 浠?V1 鐗堟湰澶囦唤", - "scheme_b_desc": "鎵弿 ~/.antigravity-agent 鐩綍锛屾壒閲忓鍏ユ棫鐗堟湰鐨勮处鍙锋暟鎹€?, - "btn_v1": "浠?V1 澶囦唤鎵归噺瀵煎叆", - "btn_custom_db": "浠庤嚜瀹氫箟 DB 瀵煎叆" + "scheme_a": "方案 A: 从当前 IDE 数据库", + "scheme_a_desc": "自动从本地 Antigravity 数据库读取当前登录的账号信息。", + "btn_db": "导入当前登录账号", + "or": "或者", + "scheme_b": "方案 B: 从 V1 版本备份", + "scheme_b_desc": "扫描 ~/.antigravity-agent 目录,批量导入旧版本的账号数据。", + "btn_v1": "从 V1 备份批量导入", + "btn_custom_db": "从自定义 DB 导入" }, - "btn_cancel": "鍙栨秷", - "btn_confirm": "纭娣诲姞", - "oauth_error": "OAuth 鎺堟潈澶辫触: {{error}}", + "btn_cancel": "取消", + "btn_confirm": "确认添加", + "oauth_error": "OAuth 授权失败: {{error}}", "status": { - "error_token": "璇峰~鍐?Refresh Token" + "error_token": "请填写 Refresh Token" } }, "table": { - "email": "閭", - "quota": "妯″瀷閰嶉", - "last_used": "鏈€鍚庝娇鐢?, - "actions": "鎿嶄綔" + "email": "邮箱", + "quota": "模型配额", + "last_used": "最后使用", + "actions": "操作" }, - "drag_to_reorder": "鎷栨嫿鎺掑簭", + "drag_to_reorder": "拖拽排序", "empty": { - "title": "鏆傛棤璐﹀彿", - "desc": "鐐瑰嚮涓婃柟\"娣诲姞璐﹀彿\"鎸夐挳娣诲姞绗竴涓处鍙? + "title": "暂无账号", + "desc": "点击上方\"添加账号\"按钮添加第一个账号" }, "views": { - "list": "鍒楄〃瑙嗗浘", - "grid": "缃戞牸瑙嗗浘" + "list": "列表视图", + "grid": "网格视图" }, "dialog": { - "add_title": "娣诲姞鏂拌处鍙?, - "batch_delete_title": "鎵归噺鍒犻櫎纭", - "delete_title": "鍒犻櫎纭", - "batch_delete_msg": "纭畾瑕佸垹闄ら€変腑鐨?{{count}} 涓处鍙峰悧锛熸鎿嶄綔鏃犳硶鎾ら攢銆?, - "delete_msg": "纭畾瑕佸垹闄よ繖涓处鍙峰悧锛熸鎿嶄綔鏃犳硶鎾ら攢銆?, - "refresh_title": "鍒锋柊閰嶉", - "batch_refresh_title": "鎵归噺鍒锋柊", - "refresh_msg": "纭畾瑕佸埛鏂板綋鍓嶈处鍙风殑閰嶉鍚楋紵", - "batch_refresh_msg": "纭畾瑕佸埛鏂伴€変腑鐨?{{count}} 涓处鍙风殑閰嶉鍚楋紵杩欏彲鑳介渶瑕佷竴浜涙椂闂淬€?, - "disable_proxy_title": "绂佺敤鍙嶄唬", - "disable_proxy_msg": "纭畾瑕佺鐢ㄦ璐﹀彿鐨勫弽浠e姛鑳藉悧锛熻处鍙蜂粛鍙湪搴旂敤涓娇鐢ㄣ€?, - "enable_proxy_title": "鍚敤鍙嶄唬", - "enable_proxy_msg": "纭畾瑕侀噸鏂板惎鐢ㄦ璐﹀彿鐨勫弽浠e姛鑳藉悧锛?, - "warmup_all_title": "鍏ㄩ噺鎵嬪姩棰勭儹", - "warmup_all_msg": "纭畾瑕佺珛鍗充负鎵€鏈夌鍚堟潯浠剁殑璐﹀彿瑙﹀彂棰勭儹浠诲姟鍚楋紵杩欏皢鍚?Google 鏈嶅姟鍙戦€佹瀬灏忔祦閲忎互閲嶇疆閰嶉閰嶉鍛ㄦ湡銆?, - "batch_warmup_title": "鎵归噺鎵嬪姩棰勭儹", - "batch_warmup_msg": "纭畾瑕佷负閫変腑鐨?{{count}} 涓处鍙风珛鍗宠Е鍙戦鐑悧锛? + "add_title": "添加新账号", + "batch_delete_title": "批量删除确认", + "delete_title": "删除确认", + "batch_delete_msg": "确定要删除选中的 {{count}} 个账号吗?此操作无法撤销。", + "delete_msg": "确定要删除这个账号吗?此操作无法撤销。", + "refresh_title": "刷新配额", + "batch_refresh_title": "批量刷新", + "refresh_msg": "确定要刷新当前账号的配额吗?", + "batch_refresh_msg": "确定要刷新选中的 {{count}} 个账号的配额吗?这可能需要一些时间。", + "disable_proxy_title": "禁用反代", + "disable_proxy_msg": "确定要禁用此账号的反代功能吗?账号仍可在应用中使用。", + "enable_proxy_title": "启用反代", + "enable_proxy_msg": "确定要重新启用此账号的反代功能吗?", + "warmup_all_title": "全量手动预热", + "warmup_all_msg": "确定要立即为所有符合条件的账号触发预热任务吗?这将向 Google 服务发送极小流量以重置配额配额周期。", + "batch_warmup_title": "批量手动预热", + "batch_warmup_msg": "确定要为选中的 {{count}} 个账号立即触发预热吗?" } }, "settings": { - "save": "淇濆瓨璁剧疆", + "save": "保存设置", "tabs": { - "general": "閫氱敤", - "account": "璐﹀彿", - "proxy": "浠g悊璁剧疆", - "advanced": "楂樼骇", - "debug": "璋冭瘯", - "about": "鍏充簬" + "general": "通用", + "account": "账号", + "proxy": "代理设置", + "advanced": "高级", + "debug": "调试", + "about": "关于" }, "general": { - "title": "閫氱敤璁剧疆", - "language": "璇█", - "theme": "涓婚", - "theme_light": "娴呰壊", - "theme_dark": "娣辫壊", - "theme_system": "璺熼殢绯荤粺", - "auto_launch": "寮€鏈鸿嚜鍔ㄥ惎鍔?, - "auto_launch_enabled": "鍚敤", - "auto_launch_disabled": "绂佺敤", - "auto_launch_desc": "绯荤粺鍚姩鏃惰嚜鍔ㄨ繍琛?Antigravity Tools", - "auto_check_update": "鑷姩妫€鏌ユ洿鏂?, - "auto_check_update_desc": "鍚姩鏃惰嚜鍔ㄦ鏌ユ柊鐗堟湰", - "auto_check_update_enabled": "宸插惎鐢ㄨ嚜鍔ㄦ鏌ユ洿鏂?, - "auto_check_update_disabled": "宸茬鐢ㄨ嚜鍔ㄦ鏌ユ洿鏂?, - "update_check_interval": "妫€鏌ラ棿闅?灏忔椂)", - "update_check_interval_desc": "璁剧疆鑷姩妫€鏌ユ洿鏂扮殑鏃堕棿闂撮殧(1-168 灏忔椂)", - "update_check_interval_saved": "宸蹭繚瀛樻鏌ラ棿闅旇缃? + "title": "通用设置", + "language": "语言", + "theme": "主题", + "theme_light": "浅色", + "theme_dark": "深色", + "theme_system": "跟随系统", + "auto_launch": "开机自动启动", + "auto_launch_enabled": "启用", + "auto_launch_disabled": "禁用", + "auto_launch_desc": "系统启动时自动运行 Antigravity Tools", + "auto_check_update": "自动检查更新", + "auto_check_update_desc": "启动时自动检查新版本", + "auto_check_update_enabled": "已启用自动检查更新", + "auto_check_update_disabled": "已禁用自动检查更新", + "update_check_interval": "检查间隔(小时)", + "update_check_interval_desc": "设置自动检查更新的时间间隔(1-168 小时)", + "update_check_interval_saved": "已保存检查间隔设置" }, "account": { - "title": "璐﹀彿璁剧疆", - "auto_refresh": "鍚庡彴鑷姩鍒锋柊", - "auto_refresh_desc": "鍚庡彴鑷姩鍒锋柊鎵€鏈夎处鍙风殑閰嶉淇℃伅锛岃繖鏄搴︿繚鎶ゅ拰鏅鸿兘棰勭儹鐨勫熀纭€銆?, - "always_on": "濮嬬粓寮€鍚?, - "refresh_interval": "鍒锋柊闂撮殧锛堝垎閽燂級", - "auto_sync": "鑷姩鑾峰彇褰撳墠璐﹀彿", - "auto_sync_desc": "瀹氭湡鑷姩鍒锋柊褰撳墠娲诲姩璐﹀彿鐨勪俊鎭?, - "sync_interval": "鍚屾闂撮殧锛堝垎閽燂級" + "title": "账号设置", + "auto_refresh": "后台自动刷新", + "auto_refresh_desc": "后台自动刷新所有账号的配额信息,这是额度保护和智能预热的基础。", + "always_on": "始终开启", + "refresh_interval": "刷新间隔(分钟)", + "auto_sync": "自动获取当前账号", + "auto_sync_desc": "定期自动刷新当前活动账号的信息", + "sync_interval": "同步间隔(分钟)" }, "warmup": { - "title": "鏅鸿兘棰勭儹", - "desc": "鑷姩鐩戞帶鎵€鏈夋ā鍨嬶紝褰撻搴︽仮澶嶅埌 100% 鏃剁珛鍗宠Е鍙戦鐑紝淇濇寔妯″瀷鐑姸鎬? + "title": "智能预热", + "desc": "自动监控所有模型,当额度恢复到 100% 时立即触发预热,保持模型热状态" }, "quota_protection": { - "title": "閰嶉淇濇姢", - "enable": "鍚敤閰嶉淇濇姢", - "enable_desc": "褰撹处鍙峰墿浣欓厤棰濅綆浜庨槇鍊兼椂鑷姩绂佺敤鍙嶄唬鍔熻兘锛岄厤棰濋噸缃悗灏嗚嚜鍔ㄦ仮澶嶈处鍙?, - "threshold_label": "淇濈暀閰嶉鐧惧垎姣?, - "monitored_models_label": "鐩戞帶妯″瀷 (瑙﹀彂鏉′欢)", - "monitored_models_desc": "鑷冲皯閫夋嫨涓€涓牳蹇冩ā鍨嬨€備换涓€鍕鹃€夋ā鍨嬮搴︿綆浜庨槇鍊煎皢瑙﹀彂淇濇姢", - "range": "鑼冨洿", - "example": "绀轰緥锛氳缃?{{percentage}}% 鏃讹紝{{total}} 娆¢厤棰濈殑璐﹀彿鍓╀綑 鈮?{{threshold}} 娆℃椂灏嗚鑷姩绂佺敤", - "auto_restore_info": "閰嶉閲嶇疆鍚庡皢鑷姩閲嶆柊鍚敤璐﹀彿" + "title": "配额保护", + "enable": "启用配额保护", + "enable_desc": "当账号剩余配额低于阈值时自动禁用反代功能,配额重置后将自动恢复账号", + "threshold_label": "保留配额百分比", + "monitored_models_label": "监控模型 (触发条件)", + "monitored_models_desc": "至少选择一个核心模型。任一勾选模型额度低于阈值将触发保护", + "range": "范围", + "example": "示例:设置 {{percentage}}% 时,{{total}} 次配额的账号剩余 ≤ {{threshold}} 次时将被自动禁用", + "auto_restore_info": "配额重置后将自动重新启用账号" }, "pinned_quota_models": { - "title": "閰嶉鍏虫敞鍒楄〃", - "desc": "閫夋嫨瑕佸湪璐﹀彿鍒楄〃澶栧眰鏄剧ず鐨勬ā鍨嬮厤棰濓紝鏈€変腑鐨勬ā鍨嬪彧鍦ㄨ鎯呭脊绐椾腑鏄剧ず" + "title": "配额关注列表", + "desc": "选择要在账号列表外层显示的模型配额,未选中的模型只在详情弹窗中显示" }, "proxy": { - "title": "浠g悊璁剧疆" + "title": "代理设置" }, "proxy_pool": { - "title": "浠g悊姹?, - "strategy_priority": "鎸夋潈閲嶉殢鏈?, - "strategy_round_robin": "椤哄簭寰幆", - "strategy_random": "闅忔満", - "strategy_least_connections": "鏈€灏戣繛鎺?, - "test_all": "鍏ㄩ噺妫€娴?, - "batch_import": "瀵煎叆", - "binding_manager": "缁戝畾", - "add_proxy": "娣诲姞浠g悊", - "edit_proxy": "缂栬緫浠g悊", - "name": "鍚嶇О", - "url": "浠g悊鍦板潃", - "username": "鐢ㄦ埛鍚?, - "password": "瀵嗙爜", - "max_accounts": "鏈€澶ц处鍙锋暟", - "max_accounts_hint": "0 = 涓嶉檺鍒?, - "priority": "浼樺厛绾?, - "priority_hint": "瓒婂皬瓒婁紭鍏?, - "health_check_url": "鍋ュ悍妫€鏌ュ湴鍧€", - "tags": "鏍囩", - "add_tag_placeholder": "娣诲姞鏍囩...", - "seconds": "绉?, - "interval_tooltip": "鍋ュ悍妫€鏌ラ棿闅?(绉?", - "test_completed": "鍋ュ悍妫€鏌ュ凡瀹屾垚", - "test_failed": "鍋ュ悍妫€鏌ュけ璐?, - "confirm_delete": "纭畾瑕佸垹闄ゆ浠g悊鍚楋紵", - "empty": "鏆傛棤浠g悊", - "column_priority": "鏉冮噸", - "column_status": "鐘舵€?, - "column_details": "浠g悊璇︽儏", - "column_bindings": "缁戝畾", - "import_title": "鎵归噺瀵煎叆浠g悊", - "import_label": "绮樿创浠g悊鍒楄〃 (姣忚涓€涓?", - "import_hint": "鏀寔鏍煎紡: protocol://user:pass@host:port, host:port:user:pass", - "import_preview": "棰勮", - "import_confirm": "瀵煎叆 {{count}} 涓唬鐞?, - "no_valid_proxies": "鏈壘鍒版湁鏁堜唬鐞?, + "title": "代理池", + "strategy_priority": "按权重随机", + "strategy_round_robin": "顺序循环", + "strategy_random": "随机", + "strategy_least_connections": "最少连接", + "test_all": "全量检测", + "batch_import": "导入", + "binding_manager": "绑定", + "add_proxy": "添加代理", + "edit_proxy": "编辑代理", + "name": "名称", + "url": "代理地址", + "username": "用户名", + "password": "密码", + "max_accounts": "最大账号数", + "max_accounts_hint": "0 = 不限制", + "priority": "优先级", + "priority_hint": "越小越优先", + "health_check_url": "健康检查地址", + "tags": "标签", + "add_tag_placeholder": "添加标签...", + "seconds": "秒", + "interval_tooltip": "健康检查间隔 (秒)", + "test_completed": "健康检查已完成", + "test_failed": "健康检查失败", + "confirm_delete": "确定要删除此代理吗?", + "empty": "暂无代理", + "column_priority": "权重", + "column_status": "状态", + "column_details": "代理详情", + "column_bindings": "绑定", + "import_title": "批量导入代理", + "import_label": "粘贴代理列表 (每行一个)", + "import_hint": "支持格式: protocol://user:pass@host:port, host:port:user:pass", + "import_preview": "预览", + "import_confirm": "导入 {{count}} 个代理", + "no_valid_proxies": "未找到有效代理", "binding": { - "title": "璐﹀彿浠g悊缁戝畾", - "load_failed": "鍔犺浇缁戝畾澶辫触", - "unbind_success": "瑙g粦鎴愬姛", - "bind_success": "缁戝畾鎴愬姛", - "update_failed": "鏇存柊缁戝畾澶辫触", - "assigned_proxy": "宸插垎閰嶄唬鐞?, - "default_strategy": "榛樿 (璺熼殢绛栫暐)" + "title": "账号代理绑定", + "load_failed": "加载绑定失败", + "unbind_success": "解绑成功", + "bind_success": "绑定成功", + "update_failed": "更新绑定失败", + "assigned_proxy": "已分配代理", + "default_strategy": "默认 (跟随策略)" }, "status": { - "inactive": "鏈惎鐢?, - "checking": "姝e湪妫€娴?, - "healthy": "姝e父", - "timeout": "宸茶秴鏃? + "inactive": "未启用", + "checking": "正在检测", + "healthy": "正常", + "timeout": "已超时" } }, "advanced": { - "title": "楂樼骇璁剧疆", - "export_path": "榛樿瀵煎嚭璺緞", - "export_path_placeholder": "鏈缃?(姣忔璇㈤棶)", - "default_export_path_desc": "璁剧疆鍚庯紝瀵煎嚭鏂囦欢灏嗙洿鎺ヤ繚瀛樺埌璇ョ洰褰曪紝涓嶅啀寮瑰嚭閫夋嫨妗?, - "select_btn": "閫夋嫨", - "open_btn": "鎵撳紑", - "data_dir": "鏁版嵁鐩綍", - "data_dir_desc": "璐﹀彿鏁版嵁鍜岄厤缃枃浠剁殑瀛樺偍浣嶇疆", - "antigravity_path": "鍙嶉噸鍔涚▼搴忚矾寰?, - "antigravity_path_placeholder": "鏈缃?(灏嗕娇鐢ㄨ嚜鍔ㄦ帰娴?", - "antigravity_path_desc": "濡傛灉鎮ㄥ皢 Antigravity 搴旂敤瀹夎鍦ㄩ潪鏍囧噯浣嶇疆锛屽彲鍦ㄦ鎵嬪姩鎸囧畾鍙墽琛屾枃浠惰矾寰勶紙MacOS 鎸囧悜 .app 鐩綍锛夈€?, - "antigravity_path_select": "閫夋嫨鍙嶉噸鍔涚▼搴忓彲鎵ц鏂囦欢", - "antigravity_path_detected": "宸叉洿鏂版帰娴嬪埌鐨勮矾寰?, - "antigravity_ide_path": "Antigravity IDE 璺緞", + "title": "高级设置", + "export_path": "默认导出路径", + "export_path_placeholder": "未设置 (每次询问)", + "default_export_path_desc": "设置后,导出文件将直接保存到该目录,不再弹出选择框", + "select_btn": "选择", + "open_btn": "打开", + "data_dir": "数据目录", + "data_dir_desc": "账号数据和配置文件的存储位置", + "antigravity_path": "反重力程序路径", + "antigravity_path_placeholder": "未设置 (将使用自动探测)", + "antigravity_path_desc": "如果您将 Antigravity 应用安装在非标准位置,可在此手动指定可执行文件路径(MacOS 指向 .app 目录)。", + "antigravity_path_select": "选择反重力程序可执行文件", + "antigravity_path_detected": "已更新探测到的路径", + "antigravity_ide_path": "Antigravity IDE 路径", "antigravity_ide_path_placeholder": "D:\\Antigravity\\Antigravity.exe", - "antigravity_ide_path_desc": "鎸囧畾 Antigravity IDE (浠g爜缂栬緫鍣? 鐨勫彲鎵ц鏂囦欢璺緞銆傝缃悗锛屽垏鎹㈣处鍙锋椂灏嗕弗鏍间繚鎶ゆ璺緞鐨勮繘绋嬩笉琚叧闂€?, - "antigravity_ide_path_select": "閫夋嫨 Antigravity IDE 鍙墽琛屾枃浠?, - "detect_btn": "鎺㈡祴", - "antigravity_args": "鍙嶉噸鍔涚▼搴忓惎鍔ㄥ弬鏁?, + "antigravity_ide_path_desc": "指定 Antigravity IDE (代码编辑器) 的可执行文件路径。设置后,切换账号时将严格保护此路径的进程不被关闭。", + "antigravity_ide_path_select": "选择 Antigravity IDE 可执行文件", + "detect_btn": "探测", + "antigravity_args": "反重力程序启动参数", "antigravity_args_placeholder": "--user-data-dir=/path/to/data --some-other-flag", - "antigravity_args_desc": "涓?Antigravity 绋嬪簭鎸囧畾鍚姩鍙傛暟锛屼緥濡?--user-data-dir 鐢ㄤ簬鎸囧畾鐢ㄦ埛鏁版嵁鐩綍", - "detect_args_btn": "妫€娴?, - "antigravity_args_detected": "鍚姩鍙傛暟宸叉洿鏂?, - "antigravity_args_detect_error": "妫€娴嬪惎鍔ㄥ弬鏁板け璐?, - "accounts_page_size": "璐﹀彿鍒楄〃鍒嗛〉澶у皬", - "page_size_auto": "鑷姩璁$畻 (鎺ㄨ崘)", - "page_size_desc": "璁剧疆姣忛〉鏄剧ず鐨勮处鍙锋暟閲忋€傞€夋嫨鑷姩璁$畻灏嗘牴鎹獥鍙eぇ灏忓姩鎬佽皟鏁淬€?, - "logs_title": "鏃ュ織缁存姢", - "logs_desc": "娓呯悊搴旂敤浜х敓鐨勬棩蹇楃紦瀛樻枃浠讹紝涓嶄細褰卞搷璐﹀彿鏁版嵁銆?, - "clear_logs": "娓呯悊鏃ュ織缂撳瓨", - "clear_logs_title": "娓呯悊鏃ュ織纭", - "clear_logs_msg": "纭畾瑕佹竻鐞嗘墍鏈夋棩蹇楃紦瀛樻枃浠跺悧锛?, - "logs_cleared": "鏃ュ織缂撳瓨宸叉竻鐞?, - "antigravity_cache_title": "Antigravity 缂撳瓨娓呯悊", - "antigravity_cache_desc": "娓呯悊 Antigravity 搴旂敤鐨勭紦瀛樺彲浠ヨВ鍐崇櫥褰曞け璐ャ€佺増鏈獙璇侀敊璇€丱Auth 鎺堟潈澶辫触绛夐棶棰樸€?, - "antigravity_cache_warning": "璇风‘淇?Antigravity 搴旂敤宸插畬鍏ㄩ€€鍑哄悗鍐嶆墽琛屾竻鐞嗘搷浣溿€?, - "clear_antigravity_cache": "娓呯悊 Antigravity 缂撳瓨", - "clear_cache_confirm_title": "纭娓呯悊 Antigravity 缂撳瓨", - "clear_cache_confirm_msg": "灏嗘竻鐞嗕互涓嬬紦瀛樼洰褰曪細", - "cache_cleared_success": "缂撳瓨娓呯悊瀹屾垚锛岄噴鏀?{{size}} MB 绌洪棿", - "cache_not_found": "鏈壘鍒?Antigravity 缂撳瓨鐩綍", - "debug_logs_title": "璋冭瘯鏃ュ織", - "debug_logs_enable_desc": "鍚敤鍚庝細璁板綍瀹屾暣璇锋眰涓庡搷搴旈摼璺紝寤鸿浠呭湪鎺掓煡闂鏃跺紑鍚€?, - "debug_logs_desc": "璁板綍瀹屾暣閾捐矾锛氬師濮嬭緭鍏ャ€佽浆鎹㈠悗鐨?v1internal 璇锋眰銆佷互鍙婁笂娓稿搷搴斻€備粎鐢ㄤ簬闂鎺掓煡锛屽彲鑳藉寘鍚晱鎰熸暟鎹€?, - "debug_log_dir": "璋冭瘯鏃ュ織杈撳嚭鐩綍", - "debug_log_dir_hint": "涓嶅~鍐欏垯浣跨敤榛樿鐩綍锛歿{path}}/debug_logs", - "debug_log_dir_select": "閫夋嫨璋冭瘯鏃ュ織杈撳嚭鐩綍", - "http_api_title": "HTTP API 鏈嶅姟", - "http_api_desc": "涓哄閮ㄧ▼搴忥紙濡?VS Code 鎻掍欢锛夋彁渚涙湰鍦?HTTP 鎺ュ彛銆?, - "http_api_enabled": "鍚敤 HTTP API", - "http_api_enabled_desc": "鍚敤鍚庯紝澶栭儴绋嬪簭鍙€氳繃 HTTP 鎺ュ彛绠$悊璐﹀彿", - "http_api_port": "鐩戝惉绔彛", - "http_api_port_desc": "淇敼绔彛鍚庨渶瑕侀噸鍚簲鐢ㄦ墠鑳界敓鏁堛€傚閬囩鍙e啿绐侊紝璇锋洿鎹负鍏朵粬鏈鍗犵敤鐨勭鍙c€?, - "http_api_port_placeholder": "榛樿绔彛 19527", - "http_api_port_invalid": "绔彛鍙锋棤鏁堬紙鑼冨洿锛?024-65535锛?, - "http_api_settings_saved": "HTTP API 璁剧疆宸蹭繚瀛橈紝閲嶅惎搴旂敤鍚庣敓鏁?, - "http_api_restart_required": "鈿狅笍 闇€瑕侀噸鍚簲鐢ㄥ悗鐢熸晥" + "antigravity_args_desc": "为 Antigravity 程序指定启动参数,例如 --user-data-dir 用于指定用户数据目录", + "detect_args_btn": "检测", + "antigravity_args_detected": "启动参数已更新", + "antigravity_args_detect_error": "检测启动参数失败", + "accounts_page_size": "账号列表分页大小", + "page_size_auto": "自动计算 (推荐)", + "page_size_desc": "设置每页显示的账号数量。选择自动计算将根据窗口大小动态调整。", + "logs_title": "日志维护", + "logs_desc": "清理应用产生的日志缓存文件,不会影响账号数据。", + "clear_logs": "清理日志缓存", + "clear_logs_title": "清理日志确认", + "clear_logs_msg": "确定要清理所有日志缓存文件吗?", + "logs_cleared": "日志缓存已清理", + "antigravity_cache_title": "Antigravity 缓存清理", + "antigravity_cache_desc": "清理 Antigravity 应用的缓存可以解决登录失败、版本验证错误、OAuth 授权失败等问题。", + "antigravity_cache_warning": "请确保 Antigravity 应用已完全退出后再执行清理操作。", + "clear_antigravity_cache": "清理 Antigravity 缓存", + "clear_cache_confirm_title": "确认清理 Antigravity 缓存", + "clear_cache_confirm_msg": "将清理以下缓存目录:", + "cache_cleared_success": "缓存清理完成,释放 {{size}} MB 空间", + "cache_not_found": "未找到 Antigravity 缓存目录", + "debug_logs_title": "调试日志", + "debug_logs_enable_desc": "启用后会记录完整请求与响应链路,建议仅在排查问题时开启。", + "debug_logs_desc": "记录完整链路:原始输入、转换后的 v1internal 请求、以及上游响应。仅用于问题排查,可能包含敏感数据。", + "debug_log_dir": "调试日志输出目录", + "debug_log_dir_hint": "不填写则使用默认目录:{{path}}/debug_logs", + "debug_log_dir_select": "选择调试日志输出目录", + "http_api_title": "HTTP API 服务", + "http_api_desc": "为外部程序(如 VS Code 插件)提供本地 HTTP 接口。", + "http_api_enabled": "启用 HTTP API", + "http_api_enabled_desc": "启用后,外部程序可通过 HTTP 接口管理账号", + "http_api_port": "监听端口", + "http_api_port_desc": "修改端口后需要重启应用才能生效。如遇端口冲突,请更换为其他未被占用的端口。", + "http_api_port_placeholder": "默认端口 19527", + "http_api_port_invalid": "端口号无效(范围:1024-65535)", + "http_api_settings_saved": "HTTP API 设置已保存,重启应用后生效", + "http_api_restart_required": "⚠️ 需要重启应用后生效" }, "debug": { - "title": "璋冭瘯鎺у埗鍙?, - "desc": "瀹炴椂鏌ョ湅搴旂敤鏃ュ織锛岀敤浜庤皟璇曞拰闂鎺掓煡", - "enabled": "宸插惎鐢?, - "disabled": "宸茬鐢?, - "disabled_hint": "璋冭瘯鎺у埗鍙板凡鍏抽棴", - "disabled_desc": "寮€鍚悗灏嗗疄鏃惰褰曞簲鐢ㄦ棩蹇?, - "console_title": "璋冭瘯鎺у埗鍙?, - "console_desc": "鏌ョ湅瀹炴椂搴旂敤鏃ュ織锛岀敤浜庢帓鏌ラ棶棰樸€?, - "enable_desc": "寮€鍚悗灏嗘崟鑾峰苟鏄剧ず鍚庣鏃ュ織銆?, - "open_btn": "鎵撳紑鎺у埗鍙?, - "debug_logging": "璋冭瘯鏃ュ織", - "debug_logging_desc": "鍚敤鍚庝細璁板綍瀹屾暣璇锋眰涓庡搷搴旈摼璺紝寤鸿浠呭湪鎺掓煡闂鏃跺紑鍚€? + "title": "调试控制台", + "desc": "实时查看应用日志,用于调试和问题排查", + "enabled": "已启用", + "disabled": "已禁用", + "disabled_hint": "调试控制台已关闭", + "disabled_desc": "开启后将实时记录应用日志", + "console_title": "调试控制台", + "console_desc": "查看实时应用日志,用于排查问题。", + "enable_desc": "开启后将捕获并显示后端日志。", + "open_btn": "打开控制台", + "debug_logging": "调试日志", + "debug_logging_desc": "启用后会记录完整请求与响应链路,建议仅在排查问题时开启。" }, "menu": { - "title": "鑿滃崟鏄剧ず璁剧疆", - "desc": "閫夋嫨瑕佸湪鑿滃崟鏍忎腑鏄剧ず鐨勫姛鑳介」銆傞殣钘忎笉甯哥敤鐨勮彍鍗曞彲浠ヨ妭鐪佺┖闂淬€?, - "selected_items_note": "琚€変腑鐨勯」鐩皢鏄剧ず鍦ㄩ《閮ㄨ彍鍗曟爮涓€?, - "required": "蹇呴€? + "title": "菜单显示设置", + "desc": "选择要在菜单栏中显示的功能项。隐藏不常用的菜单可以节省空间。", + "selected_items_note": "被选中的项目将显示在顶部菜单栏中。", + "required": "必选" }, "about": { - "title": "鍏充簬", - "version": "搴旂敤鐗堟湰", - "tech_stack": "鎶€鏈爤", - "author": "浣滆€?, - "wechat": "寰俊鍏紬鍙?, - "telegram": "Telegram 棰戦亾", - "github": "寮€婧愬湴鍧€", - "view_code": "鏌ョ湅浠g爜", - "copyright": "Copyright 漏 2025-2026 Antigravity. All rights reserved.", - "check_update": "妫€娴嬫洿鏂?, - "checking_update": "妫€娴嬩腑...", - "latest_version": "宸叉槸鏈€鏂扮増鏈?, - "new_version_available": "鍙戠幇鏂扮増鏈?{{version}}", - "download_update": "鍓嶅線涓嬭浇", - "brew_upgrade": "閫氳繃 Homebrew 鏇存柊", - "brew_upgrading": "鏇存柊涓?..", - "brew_confirm_title": "閫氳繃 Homebrew 鏇存柊", - "brew_confirm_desc": "鍗冲皢鎵ц浠ヤ笅鍛戒护鏇存柊搴旂敤锛屾洿鏂板畬鎴愬悗闇€瑕侀噸鍚簲鐢ㄣ€?, - "brew_quarantine_hint": "濡傛洿鏂板悗閬囧埌銆屽簲鐢ㄥ凡鎹熷潖銆嶆彁绀猴紝璇峰湪缁堢杩愯锛?, - "brew_confirm_btn": "寮€濮嬫洿鏂?, - "brew_success_title": "鍗囩骇瀹屾垚", - "brew_upgrade_success": "Homebrew 鍗囩骇鎴愬姛锛岃閲嶅惎搴旂敤浠ュ姞杞芥柊鐗堟湰銆?, - "brew_restart_btn": "绔嬪嵆閲嶅惎", - "brew_restart_failed": "鑷姩閲嶅惎澶辫触锛岃鎵嬪姩鍏抽棴骞堕噸鏂版墦寮€搴旂敤", - "brew_upgrade_failed": "Homebrew 鍗囩骇澶辫触锛岃灏濊瘯鍦ㄧ粓绔墜鍔ㄦ墽琛岋細brew upgrade --cask antigravity-tools", - "brew_error_brew_not_found": "鏈壘鍒?Homebrew锛岃纭宸插畨瑁?brew", - "brew_error_brew_exec_failed": "鎵ц brew 鍛戒护澶辫触锛岃灏濊瘯鍦ㄧ粓绔墜鍔ㄦ墽琛?, - "brew_error_brew_timeout": "Homebrew 鍗囩骇瓒呮椂锛?鍒嗛挓锛夛紝璇峰湪缁堢鎵嬪姩鎵ц锛歜rew upgrade --cask antigravity-tools", - "brew_error_brew_already_latest": "宸叉槸鏈€鏂扮増鏈紝鏃犻渶鍗囩骇", - "brew_error_brew_not_supported": "褰撳墠绯荤粺涓嶆敮鎸?Homebrew 鏇存柊", - "update_check_failed": "妫€娴嬫洿鏂板け璐?, - "support_btn": "鏀寔浣滆€?, - "support_title": "璧炲姪鏀寔", - "support_desc": "濡傛灉鎮ㄨ寰楁湰宸ュ叿瀵规偍鏈夊府鍔╋紝娆㈣繋鎵爜璇蜂綔鑰呭枬鏉挅鍟★紒鎮ㄧ殑鏀寔鏄垜鎸佺画缁存姢椤圭洰鐨勬渶澶у姩鍔涖€?, - "support_alipay": "鏀粯瀹?, - "support_wechat": "寰俊鏀粯", + "title": "关于", + "version": "应用版本", + "tech_stack": "技术栈", + "author": "作者", + "wechat": "微信公众号", + "telegram": "Telegram 频道", + "github": "开源地址", + "view_code": "查看代码", + "copyright": "Copyright © 2025-2026 Antigravity. All rights reserved.", + "check_update": "检测更新", + "checking_update": "检测中...", + "latest_version": "已是最新版本", + "new_version_available": "发现新版本 {{version}}", + "download_update": "前往下载", + "brew_upgrade": "通过 Homebrew 更新", + "brew_upgrading": "更新中...", + "brew_confirm_title": "通过 Homebrew 更新", + "brew_confirm_desc": "即将执行以下命令更新应用,更新完成后需要重启应用。", + "brew_quarantine_hint": "如更新后遇到「应用已损坏」提示,请在终端运行:", + "brew_confirm_btn": "开始更新", + "brew_success_title": "升级完成", + "brew_upgrade_success": "Homebrew 升级成功,请重启应用以加载新版本。", + "brew_restart_btn": "立即重启", + "brew_restart_failed": "自动重启失败,请手动关闭并重新打开应用", + "brew_upgrade_failed": "Homebrew 升级失败,请尝试在终端手动执行:brew upgrade --cask antigravity-tools", + "brew_error_brew_not_found": "未找到 Homebrew,请确认已安装 brew", + "brew_error_brew_exec_failed": "执行 brew 命令失败,请尝试在终端手动执行", + "brew_error_brew_timeout": "Homebrew 升级超时(3分钟),请在终端手动执行:brew upgrade --cask antigravity-tools", + "brew_error_brew_already_latest": "已是最新版本,无需升级", + "brew_error_brew_not_supported": "当前系统不支持 Homebrew 更新", + "update_check_failed": "检测更新失败", + "support_btn": "支持作者", + "support_title": "赞助支持", + "support_desc": "如果您觉得本工具对您有帮助,欢迎扫码请作者喝杯咖啡!您的支持是我持续维护项目的最大动力。", + "support_alipay": "支付宝", + "support_wechat": "微信支付", "support_buymeacoffee": "Buy Me a Coffee" }, "advanced_thinking": { - "title": "楂樼骇鎬濈淮涓庡叏灞€閰嶇疆", - "description": "闆嗕腑绠$悊鎬濊€冭兘鍔涖€佸浘鍍忔ā寮忓強鍏ㄥ眬鎸囦护銆? + "title": "高级思维与全局配置", + "description": "集中管理思考能力、图像模式及全局指令。" }, "thinking_budget": { - "title": "鎬濊€冮绠?(Thinking Budget)", - "description": "鎺у埗 AI 娣卞害鎬濊€冩椂鐨?Token 棰勭畻銆傛煇浜涙ā鍨嬶紙濡?Flash銆佸甫 -thinking 鍚庣紑鐨勬ā鍨嬶級鍙椾笂娓?24576 涓婇檺闄愬埗銆?, - "mode_label": "澶勭悊妯″紡", + "title": "思考预算 (Thinking Budget)", + "description": "控制 AI 深度思考时的 Token 预算。某些模型(如 Flash、带 -thinking 后缀的模型)受上游 24576 上限限制。", + "mode_label": "处理模式", "mode": { - "auto": "鑷姩闄愬埗", - "passthrough": "閫忎紶", - "custom": "鑷畾涔?, - "adaptive": "鑷€傚簲" + "auto": "自动限制", + "passthrough": "透传", + "custom": "自定义", + "adaptive": "自适应" }, - "effort_label": "鎬濊€冨己搴?, + "effort_label": "思考强度", "effort": { - "low": "浣?(Low)", - "medium": "涓?(Medium)", - "high": "楂?(High)" + "low": "低 (Low)", + "medium": "中 (Medium)", + "high": "高 (High)" }, - "auto_hint": "鑷姩妯″紡锛氬 Flash 妯″瀷銆?thinking 鍚庣紑妯″瀷銆佷互鍙婂惎鐢?Web Search 鐨勮姹傝嚜鍔ㄩ檺鍒跺湪 24576 浠ラ伩鍏?API 閿欒銆?, - "passthrough_warning": "閫忎紶锛氱洿鎺ヤ娇鐢ㄨ皟鐢ㄦ柟鍘熷鍊硷紝涓嶆敮鎸侀珮鍊煎彲鑳藉鑷村け璐ャ€?, - "custom_value_hint": "鎺ㄨ崘锛?4576 (Flash) 鎴?51200 (鎵╁睍)", - "adaptive_hint": "鑷€傚簲妯″紡锛氱敱妯″瀷鏍规嵁浠诲姟澶嶆潅搴﹁嚜鍔ㄨ皟鏁存€濊€冮噺銆侰laude 4.6+ 鎺ㄨ崘浣跨敤姝ゆā寮忋€?, + "auto_hint": "自动模式:对 Flash 模型、-thinking 后缀模型、以及启用 Web Search 的请求自动限制在 24576 以避免 API 错误。", + "passthrough_warning": "透传:直接使用调用方原始值,不支持高值可能导致失败。", + "custom_value_hint": "推荐:24576 (Flash) 或 51200 (扩展)", + "adaptive_hint": "自适应模式:由模型根据任务复杂度自动调整思考量。Claude 4.6+ 推荐使用此模式。", "tokens": "tokens" }, "image_thinking_mode": { - "title": "鍥惧儚鎬濈淮妯″紡 (Image Thinking Mode)", - "hint": "褰卞搷鐢昏川涓庣敓鎴愭祦绋?, + "title": "图像思维模式 (Image Thinking Mode)", + "hint": "影响画质与生成流程", "options": { - "enabled": "寮€鍚?, - "disabled": "鍏抽棴", - "enabled_desc": "寮€鍚細淇濈暀鎬濈淮閾撅紝杩斿洖鑽夊浘 + 鎴愬搧鍙屽浘銆?, - "disabled_desc": "鍏抽棴锛氱鐢ㄦ€濈淮閾撅紝鐩存帴鐢熸垚鍗曞紶瓒呮竻鍥剧墖锛堢敾璐ㄤ紭鍏堬級銆? + "enabled": "开启", + "disabled": "关闭", + "enabled_desc": "开启:保留思维链,返回草图 + 成品双图。", + "disabled_desc": "关闭:禁用思维链,直接生成单张超清图片(画质优先)。" } }, "global_system_prompt": { - "title": "鍏ㄥ眬绯荤粺鎻愮ず璇?(Global System Prompt)", - "hint": "鑷姩娉ㄥ叆鎵€鏈夎姹傜殑 systemInstruction", - "placeholder": "杈撳叆鍏ㄥ眬绯荤粺鎻愮ず璇?..\n渚嬪锛氫綘鏄竴浣嶈祫娣辩殑鍏ㄦ爤寮€鍙戝伐绋嬪笀锛屾搮闀?React 鍜?Rust銆傝浣跨敤绠€浣撲腑鏂囧洖澶嶃€?, - "char_count": "{{count}} 瀛楃", - "long_prompt_warning": "鎻愮ず璇嶈緝闀匡紙瓒呰繃 2000 瀛楃锛夛紝鍙兘浼氬崰鐢ㄨ緝澶氱殑涓婁笅鏂囩獥鍙g┖闂淬€? + "title": "全局系统提示词 (Global System Prompt)", + "hint": "自动注入所有请求的 systemInstruction", + "placeholder": "输入全局系统提示词...\n例如:你是一位资深的全栈开发工程师,擅长 React 和 Rust。请使用简体中文回复。", + "char_count": "{{count}} 字符", + "long_prompt_warning": "提示词较长(超过 2000 字符),可能会占用较多的上下文窗口空间。" } }, "tray": { - "current": "褰撳墠", - "quota": "棰濆害", - "switch_next": "鍒囨崲涓嬩竴涓处鍙?, - "refresh_current": "鍒锋柊褰撳墠璐﹀彿棰濆害", - "show_window": "鏄剧ず涓荤獥鍙?, - "quit": "閫€鍑哄簲鐢?(Exit)", - "no_account": "鏃犺处鍙?, - "unknown_quota": "鏈煡 (鐐瑰嚮鍒锋柊)", - "forbidden": "璐﹀彿琚皝绂? + "current": "当前", + "quota": "额度", + "switch_next": "切换下一个账号", + "refresh_current": "刷新当前账号额度", + "show_window": "显示主窗口", + "quit": "退出应用 (Exit)", + "no_account": "无账号", + "unknown_quota": "未知 (点击刷新)", + "forbidden": "账号被封禁" }, "proxy": { - "title": "API 鍙嶄唬鏈嶅姟", + "title": "API 反代服务", "status": { - "running": "鏈嶅姟杩愯涓?, - "stopped": "鏈嶅姟宸插仠姝?, - "accounts_available": "{{count}} 涓处鍙峰彲鐢?, - "processing": "澶勭悊涓?.." + "running": "服务运行中", + "stopped": "服务已停止", + "accounts_available": "{{count}} 个账号可用", + "processing": "处理中..." }, "action": { - "start": "鍚姩鏈嶅姟", - "stop": "鍋滄鏈嶅姟" + "start": "启动服务", + "stop": "停止服务" }, "config": { - "title": "鏈嶅姟閰嶇疆", + "title": "服务配置", "request": { - "user_agent": "User-Agent 瑕嗙洊", - "user_agent_tooltip": "鑷畾涔夊彂閫佺粰涓婃父 API 鐨?User-Agent 璇锋眰澶淬€傜暀绌哄垯浣跨敤榛樿鍊笺€?, - "user_agent_hint": "褰撳墠榛樿鍊? antigravity/ /", - "user_agent_placeholder": "杈撳叆鑷畾涔?User-Agent 瀛楃涓?.." + "user_agent": "User-Agent 覆盖", + "user_agent_tooltip": "自定义发送给上游 API 的 User-Agent 请求头。留空则使用默认值。", + "user_agent_hint": "当前默认值: antigravity/ /", + "user_agent_placeholder": "输入自定义 User-Agent 字符串..." }, - "port": "鐩戝惉绔彛", - "port_tooltip": "鏈湴 API 浠g悊鐩戝惉鐨勭鍙c€傞渶瑕佸厛鍋滄鏈嶅姟鍐嶄慨鏀癸紝淇敼鍚庨渶閲嶅惎鐢熸晥銆?, - "port_hint": "榛樿 8045锛屼慨鏀圭鍙i渶閲嶅惎鏈嶅姟", - "auto_start": "璺熼殢搴旂敤鑷姩鍚姩", - "auto_start_tooltip": "搴旂敤鍚姩鏃惰嚜鍔ㄥ惎鍔ㄦ湰鍦?API 浠g悊鏈嶅姟銆?, - "allow_lan_access": "鍏佽灞€鍩熺綉璁块棶", - "allow_lan_access_tooltip": "寮€鍚悗缁戝畾鍒?0.0.0.0锛屽眬鍩熺綉鍏朵粬璁惧涔熻兘璁块棶銆傚缓璁悓鏃跺紑鍚壌鏉冨苟濡ュ杽淇濈 API 瀵嗛挜锛涗慨鏀瑰悗闇€閲嶅惎鐢熸晥銆?, - "allow_lan_access_hint_enabled": "馃寪 鐩戝惉 0.0.0.0锛屽眬鍩熺綉璁惧鍙闂?, - "allow_lan_access_hint_disabled": "馃敀 浠呯洃鍚?127.0.0.1锛屼粎鏈満鍙闂紙闅愮浼樺厛锛?, - "allow_lan_access_warning": "鈿狅笍 寮€鍚悗灞€鍩熺綉鍐呭叾浠栬澶囧彲璁块棶锛岃纭繚 API 瀵嗛挜瀹夊叏", - "allow_lan_access_restart_hint": "鈩癸笍 闇€瑕侀噸鍚湇鍔″悗鐢熸晥", - "api_key": "API 瀵嗛挜", - "api_key_tooltip": "鍚敤閴存潈鍚庯紝瀹㈡埛绔闂唬鐞嗘墍闇€鐨勫叡浜瘑閽ャ€傞噸鏂扮敓鎴愪細绔嬪嵆浣挎棫瀵嗛挜澶辨晥銆?, - "btn_regenerate": "閲嶆柊鐢熸垚瀵嗛挜", - "btn_edit": "缂栬緫", - "btn_save": "淇濆瓨", - "btn_copy": "澶嶅埗", - "btn_copied": "宸插鍒?, - "warning_key": "娉ㄦ剰锛氳濡ュ杽淇濈鎮ㄧ殑 API 瀵嗛挜锛屼笉瑕佹硠闇茬粰浠栦汉銆?, - "api_key_invalid": "API 瀵嗛挜鏍煎紡鏃犳晥,蹇呴』浠?sk- 寮€澶翠笖闀垮害鑷冲皯 10 涓瓧绗?, - "api_key_updated": "API 瀵嗛挜宸叉洿鏂?, - "admin_password": "Web UI 绠$悊鍚庡彴瀵嗙爜", - "admin_password_tooltip": "鐢ㄤ簬鐧诲綍 Web 绠$悊鍚庡彴鐨勫瘑鐮併€傚鏋滀负绌猴紝鍒欓粯璁や娇鐢?API 瀵嗛挜锛圓PI Key锛夈€?, - "admin_password_default": "锛堝悓 API 瀵嗛挜锛?, - "admin_password_placeholder": "杈撳叆鏂板瘑鐮侊紝鐣欑┖鍒欎娇鐢?API 瀵嗛挜", - "admin_password_hint": "鎻愮ず锛氬湪 Docker/Web 閮ㄧ讲鍦烘櫙涓紝鎮ㄥ彲浠ヨ缃竴涓嫭绔嬬殑鐧诲綍瀵嗙爜锛屾彁楂?API 瀵嗛挜鐨勫畨鍏ㄦ€с€?, - "admin_password_short": "瀵嗙爜澶煭锛堟渶灏?4 涓瓧绗︼級", - "admin_password_updated": "Web UI 鐧诲綍瀵嗙爜宸叉洿鏂?, + "port": "监听端口", + "port_tooltip": "本地 API 代理监听的端口。需要先停止服务再修改,修改后需重启生效。", + "port_hint": "默认 8045,修改端口需重启服务", + "auto_start": "跟随应用自动启动", + "auto_start_tooltip": "应用启动时自动启动本地 API 代理服务。", + "allow_lan_access": "允许局域网访问", + "allow_lan_access_tooltip": "开启后绑定到 0.0.0.0,局域网其他设备也能访问。建议同时开启鉴权并妥善保管 API 密钥;修改后需重启生效。", + "allow_lan_access_hint_enabled": "🌐 监听 0.0.0.0,局域网设备可访问", + "allow_lan_access_hint_disabled": "🔒 仅监听 127.0.0.1,仅本机可访问(隐私优先)", + "allow_lan_access_warning": "⚠️ 开启后局域网内其他设备可访问,请确保 API 密钥安全", + "allow_lan_access_restart_hint": "ℹ️ 需要重启服务后生效", + "api_key": "API 密钥", + "api_key_tooltip": "启用鉴权后,客户端访问代理所需的共享密钥。重新生成会立即使旧密钥失效。", + "btn_regenerate": "重新生成密钥", + "btn_edit": "编辑", + "btn_save": "保存", + "btn_copy": "复制", + "btn_copied": "已复制", + "warning_key": "注意:请妥善保管您的 API 密钥,不要泄露给他人。", + "api_key_invalid": "API 密钥格式无效,必须以 sk- 开头且长度至少 10 个字符", + "api_key_updated": "API 密钥已更新", + "admin_password": "Web UI 管理后台密码", + "admin_password_tooltip": "用于登录 Web 管理后台的密码。如果为空,则默认使用 API 密钥(API Key)。", + "admin_password_default": "(同 API 密钥)", + "admin_password_placeholder": "输入新密码,留空则使用 API 密钥", + "admin_password_hint": "提示:在 Docker/Web 部署场景中,您可以设置一个独立的登录密码,提高 API 密钥的安全性。", + "admin_password_short": "密码太短(最少 4 个字符)", + "admin_password_updated": "Web UI 登录密码已更新", "auth": { - "title": "璁块棶鎺堟潈", - "title_tooltip": "鎺у埗浠g悊鏄惁闇€瑕侀壌鏉冿紝浠ュ強鍝簺璺敱闇€瑕佹彁渚?API 瀵嗛挜銆?, - "enabled": "宸插惎鐢?, - "enabled_tooltip": "蹇€熷紑鍏抽壌鏉冿紙閫氳繃鍒囨崲閴存潈妯″紡瀹炵幇锛夈€傚紑鍚悗瀹㈡埛绔渶鍦ㄨ姹傚ご鎻愪緵 Authorization: Bearer 鎴?x-api-key銆?, - "mode": "妯″紡", - "mode_tooltip": "閫夋嫨閴存潈瑕嗙洊鑼冨洿锛氬叧闂?涓嶉壌鏉冿紱鍏ㄥ眬=鎵€鏈夋帴鍙i兘闇€瀵嗛挜锛涢櫎鍋ュ悍妫€鏌ュ=/healthz 涓嶉壌鏉冿紱鑷姩=鏈満妯″紡榛樿鍏抽棴锛屽眬鍩熺綉妯″紡榛樿鈥滈櫎鍋ュ悍妫€鏌ュ鈥濄€?, - "hint": "寮€鍚悗瀹㈡埛绔渶閫氳繃 Authorization: Bearer ... 浼犲叆 API 瀵嗛挜锛堝閫夋嫨鈥滈櫎鍋ュ悍妫€鏌ュ鈥濆垯 /healthz 鍏嶉壌鏉冿級銆?, + "title": "访问授权", + "title_tooltip": "控制代理是否需要鉴权,以及哪些路由需要提供 API 密钥。", + "enabled": "已启用", + "enabled_tooltip": "快速开关鉴权(通过切换鉴权模式实现)。开启后客户端需在请求头提供 Authorization: Bearer 或 x-api-key。", + "mode": "模式", + "mode_tooltip": "选择鉴权覆盖范围:关闭=不鉴权;全局=所有接口都需密钥;除健康检查外=/healthz 不鉴权;自动=本机模式默认关闭,局域网模式默认“除健康检查外”。", + "hint": "开启后客户端需通过 Authorization: Bearer ... 传入 API 密钥(如选择“除健康检查外”则 /healthz 免鉴权)。", "modes": { - "off": "鍏抽棴锛堝紑鏀撅級", - "strict": "鍏ㄥ眬锛堜弗鏍硷級", - "all_except_health": "鍏ㄥ眬锛堥櫎鍋ュ悍妫€鏌ュ锛?, - "auto": "鑷姩锛堟帹鑽愶級" + "off": "关闭(开放)", + "strict": "全局(严格)", + "all_except_health": "全局(除健康检查外)", + "auto": "自动(推荐)" } }, "zai": { - "title": "z.ai锛圙LM锛夋彁渚涘晢", - "title_tooltip": "涓?Claude 鍗忚鎻愪緵鍙€夌殑 Anthropic 鍏煎涓婃父锛坺.ai锛夈€傚彧褰卞搷 Claude 鍗忚璇锋眰锛孏oogle 璐﹀彿姹犱粛鎸夊師閫昏緫宸ヤ綔銆?, - "subtitle": "鍙€夌殑 Anthropic 鍏煎涓婃父锛屼粎鐢ㄤ簬 Claude 鍗忚璇锋眰銆?, - "enabled": "宸插惎鐢?, - "enabled_tooltip": "鍚敤鍚庯紝Claude 鍗忚璇锋眰灏嗘寜鈥滃垎鍙戞ā寮忊€濊矾鐢卞埌 z.ai銆?, + "title": "z.ai(GLM)提供商", + "title_tooltip": "为 Claude 协议提供可选的 Anthropic 兼容上游(z.ai)。只影响 Claude 协议请求,Google 账号池仍按原逻辑工作。", + "subtitle": "可选的 Anthropic 兼容上游,仅用于 Claude 协议请求。", + "enabled": "已启用", + "enabled_tooltip": "启用后,Claude 协议请求将按“分发模式”路由到 z.ai。", "base_url": "Base URL", - "base_url_tooltip": "z.ai Anthropic 鍏煎鎺ュ彛鐨勫熀纭€鍦板潃銆傞粯璁?https://api.z.ai/api/anthropic锛屼唬鐞嗕細鍦ㄥ叾鍚庢嫾鎺?/v1/messages 绛夎矾寰勩€?, - "dispatch_mode": "鍒嗗彂妯″紡", - "dispatch_mode_tooltip": "鎺у埗浣曟椂浣跨敤 z.ai锛氬叧闂?涓嶄娇鐢紱鍏ㄩ儴 Claude 璇锋眰=鎵€鏈?/v1/messages 绛夐兘杞彂鍒?z.ai锛涘姞鍏ラ槦鍒?鎶?z.ai 褰撲綔闃熷垪涓殑 1 涓Ы浣嶆寜杞鍒嗛厤锛涗粎鍏滃簳=浠呭綋娌℃湁鍙敤 Google 璐﹀彿鏃舵墠浣跨敤銆?, + "base_url_tooltip": "z.ai Anthropic 兼容接口的基础地址。默认 https://api.z.ai/api/anthropic,代理会在其后拼接 /v1/messages 等路径。", + "dispatch_mode": "分发模式", + "dispatch_mode_tooltip": "控制何时使用 z.ai:关闭=不使用;全部 Claude 请求=所有 /v1/messages 等都转发到 z.ai;加入队列=把 z.ai 当作队列中的 1 个槽位按轮询分配;仅兜底=仅当没有可用 Google 账号时才使用。", "api_key": "API Key", - "api_key_tooltip": "鐢ㄤ簬璋冪敤 z.ai 涓婃父鐨?API Key锛堟湰鍦板瓨鍌級銆傚惎鐢?z.ai 鎴?MCP 鍔熻兘鍓嶅繀椤婚厤缃€?, - "api_key_placeholder": "鍦ㄦ绮樿创 z.ai API Key", - "warning": "鎻愮ず锛氳 Key 灏嗕繚瀛樺湪鏈満搴旂敤鏁版嵁鐩綍涓€?, + "api_key_tooltip": "用于调用 z.ai 上游的 API Key(本地存储)。启用 z.ai 或 MCP 功能前必须配置。", + "api_key_placeholder": "在此粘贴 z.ai API Key", + "warning": "提示:该 Key 将保存在本机应用数据目录中。", "models": { - "title": "妯″瀷鏄犲皠", - "title_tooltip": "浠?z.ai 鎷夊彇鍙敤妯″瀷 ID锛屽苟閰嶇疆濡備綍鎶?Claude/Anthropic 鐨?model 鍚嶇О杞崲涓?z.ai 鐨勬ā鍨?ID銆?, - "refresh": "鎷夊彇妯″瀷", - "refreshing": "鎷夊彇涓?..", - "hint": "鍙敤妯″瀷锛歿{count}}銆傚彲浠庡缓璁腑閫夋嫨锛屾垨鎵嬪姩杈撳叆鑷畾涔夋ā鍨?ID銆?, - "error": "鎷夊彇妯″瀷澶辫触锛歿{error}}", - "select_placeholder": "閫夋嫨妯″瀷...", - "opus": "Opus 瀹舵棌 鈫?z.ai 妯″瀷", - "opus_tooltip": "褰撹姹傜殑 model 鍖呭惈鈥渙pus鈥濓紙濡?claude-opus-*锛夋椂榛樿浣跨敤鐨?z.ai 妯″瀷 ID銆?, - "sonnet": "Sonnet 瀹舵棌 鈫?z.ai 妯″瀷", - "sonnet_tooltip": "鍏朵粬 Claude 妯″瀷锛堝 claude-sonnet-* 浠ュ強澶у鏁?claude-*锛夐粯璁や娇鐢ㄧ殑 z.ai 妯″瀷 ID銆?, - "haiku": "Haiku 瀹舵棌 鈫?z.ai 妯″瀷", - "haiku_tooltip": "褰撹姹傜殑 model 鍖呭惈鈥渉aiku鈥濓紙濡?claude-haiku-*锛夋椂榛樿浣跨敤鐨?z.ai 妯″瀷 ID銆?, - "advanced_title": "楂樼骇瑕嗙洊瑙勫垯", - "advanced_tooltip": "鍙€夌殑绮剧‘鍖归厤瑕嗙洊瑙勫垯锛氬鏋?incoming model 瀛楃涓蹭笌瑙勫垯閿畬鍏ㄤ竴鑷达紝鍒欐浛鎹负瀵瑰簲鐨?z.ai 妯″瀷 ID銆?, + "title": "模型映射", + "title_tooltip": "从 z.ai 拉取可用模型 ID,并配置如何把 Claude/Anthropic 的 model 名称转换为 z.ai 的模型 ID。", + "refresh": "拉取模型", + "refreshing": "拉取中...", + "hint": "可用模型:{{count}}。可从建议中选择,或手动输入自定义模型 ID。", + "error": "拉取模型失败:{{error}}", + "select_placeholder": "选择模型...", + "opus": "Opus 家族 → z.ai 模型", + "opus_tooltip": "当请求的 model 包含“opus”(如 claude-opus-*)时默认使用的 z.ai 模型 ID。", + "sonnet": "Sonnet 家族 → z.ai 模型", + "sonnet_tooltip": "其他 Claude 模型(如 claude-sonnet-* 以及大多数 claude-*)默认使用的 z.ai 模型 ID。", + "haiku": "Haiku 家族 → z.ai 模型", + "haiku_tooltip": "当请求的 model 包含“haiku”(如 claude-haiku-*)时默认使用的 z.ai 模型 ID。", + "advanced_title": "高级覆盖规则", + "advanced_tooltip": "可选的精确匹配覆盖规则:如果 incoming model 字符串与规则键完全一致,则替换为对应的 z.ai 模型 ID。", "from_label": "incoming model", - "to_label": "z.ai 妯″瀷", - "add_rule": "娣诲姞", - "empty": "灏氭湭閰嶇疆鑷畾涔夋浛鎹㈣鍒欍€?, - "from_placeholder": "婧愭ā鍨?(濡?claude-3-opus)", - "to_placeholder": "鏄犲皠鑷?(濡?glm-4)" + "to_label": "z.ai 模型", + "add_rule": "添加", + "empty": "尚未配置自定义替换规则。", + "from_placeholder": "源模型 (如 claude-3-opus)", + "to_placeholder": "映射至 (如 glm-4)" }, "modes": { - "off": "鍏抽棴", - "exclusive": "鍏ㄩ儴 Claude 璇锋眰璧?z.ai", - "pooled": "鍔犲叆闃熷垪锛堝崰 1 涓Ы浣嶏級", - "fallback": "浠呭厹搴? + "off": "关闭", + "exclusive": "全部 Claude 请求走 z.ai", + "pooled": "加入队列(占 1 个槽位)", + "fallback": "仅兜底" }, "mcp": { - "title": "MCP 鏈嶅姟锛堥€氳繃鏈湴浠g悊锛?, - "title_tooltip": "鍦ㄦ湰鍦颁唬鐞嗕笂鏆撮湶鍙€夌殑 /mcp/* 绔偣锛屼緵 MCP 瀹㈡埛绔洿杩炪€備粎鍦ㄦ湇鍔¤繍琛屻€亃.ai 閰嶇疆瀹屾垚涓斿搴斿紑鍏冲紑鍚椂鍙敤銆?, - "enabled": "鍚敤 MCP 鍙嶄唬", - "enabled_tooltip": "MCP 绔偣鎬诲紑鍏筹紱鍏抽棴鏃舵墍鏈?/mcp/* 璺敱灏嗚繑鍥?404銆?, - "web_search": "缃戦〉鎼滅储", - "web_search_tooltip": "鍚敤鍚庡紑鏀?/mcp/web_search_prime/mcp锛屽苟杞彂鍒?z.ai 鐨?Web Search MCP 涓婃父銆?, - "web_reader": "缃戦〉闃呰", - "web_reader_tooltip": "鍚敤鍚庡紑鏀?/mcp/web_reader/mcp锛屽苟杞彂鍒?z.ai 鐨?Web Reader MCP 涓婃父銆?, - "vision": "瑙嗚", - "vision_tooltip": "鍚敤鍚庡紑鏀?/mcp/zai-mcp-server/mcp锛堟湰鍦?MCP 鏈嶅姟锛夛紝鎻愪緵瑙嗚鐩稿叧宸ュ叿鑳藉姏锛屽苟閫氳繃 z.ai 鎵ц銆?, - "local_endpoints": "鏈湴鍦板潃锛堝湪 MCP 瀹㈡埛绔腑閰嶇疆浠ヤ笅 URL锛夛細", - "local_endpoints_tooltip": "鎶婅繖浜?URL 濉埌浣犵殑 MCP 瀹㈡埛绔噷鍗冲彲銆傚畠浠娇鐢ㄥ悓涓€涓唬鐞嗙鍙o紝骞堕伒寰綋鍓嶇殑閴存潈绛栫暐銆? + "title": "MCP 服务(通过本地代理)", + "title_tooltip": "在本地代理上暴露可选的 /mcp/* 端点,供 MCP 客户端直连。仅在服务运行、z.ai 配置完成且对应开关开启时可用。", + "enabled": "启用 MCP 反代", + "enabled_tooltip": "MCP 端点总开关;关闭时所有 /mcp/* 路由将返回 404。", + "web_search": "网页搜索", + "web_search_tooltip": "启用后开放 /mcp/web_search_prime/mcp,并转发到 z.ai 的 Web Search MCP 上游。", + "web_reader": "网页阅读", + "web_reader_tooltip": "启用后开放 /mcp/web_reader/mcp,并转发到 z.ai 的 Web Reader MCP 上游。", + "vision": "视觉", + "vision_tooltip": "启用后开放 /mcp/zai-mcp-server/mcp(本地 MCP 服务),提供视觉相关工具能力,并通过 z.ai 执行。", + "local_endpoints": "本地地址(在 MCP 客户端中配置以下 URL):", + "local_endpoints_tooltip": "把这些 URL 填到你的 MCP 客户端里即可。它们使用同一个代理端口,并遵循当前的鉴权策略。" } }, - "request_timeout": "璇锋眰瓒呮椂", - "request_timeout_tooltip": "浠g悊绛夊緟涓婃父鍝嶅簲鐨勬渶澶ф椂闂达紙绉掞級锛屽寘鍚祦寮忚緭鍑恒€傞暱鏂囨湰/闀挎帹鐞嗗彲閫傚綋璋冨ぇ锛涗慨鏀瑰悗闇€閲嶅惎鐢熸晥銆?, - "request_timeout_hint": "榛樿 120 绉掞紝鑼冨洿 30-7200 绉掋€備慨鏀瑰悗闇€閲嶅惎鏈嶅姟鐢熸晥銆?, - "enable_logging": "鍚敤璇锋眰鏃ュ織", - "enable_logging_hint": "璁板綍鍘嗗彶璁板綍浠ヤ究璋冭瘯 (寰皬鎬ц兘鎹熻€?", + "request_timeout": "请求超时", + "request_timeout_tooltip": "代理等待上游响应的最大时间(秒),包含流式输出。长文本/长推理可适当调大;修改后需重启生效。", + "request_timeout_hint": "默认 120 秒,范围 30-7200 秒。修改后需重启服务生效。", + "enable_logging": "启用请求日志", + "enable_logging_hint": "记录历史记录以便调试 (微小性能损耗)", "upstream_proxy": { - "title": "鍏ㄥ眬涓婃父浠g悊 (Global Proxy)", - "desc": "寮€鍚悗锛屽簲鐢ㄥ唴鎵€鏈夊閮ㄨ姹傦紙API 鍙嶄唬銆乀oken 鍒锋柊銆侀厤棰濇煡璇€佹洿鏂版娴嬶級閮藉皢閫氳繃姝や唬鐞嗐€?, - "desc_short": "鐢ㄤ簬鏃犳硶鍖归厤浠g悊姹犺处鍙锋椂鐨勯€氱敤鍑哄彛鎴栭檷绾ф柟妗堛€?, - "enable": "鍚敤涓婃父浠g悊", - "url": "浠g悊鍦板潃", - "url_placeholder": "渚嬪: http://127.0.0.1:7890 鎴?socks5://127.0.0.1:7890", - "tip": "鏀寔 HTTP銆丠TTPS 鍜?SOCKS5 鍗忚銆?, - "socks5h_hint": "鑻ラ渶閬垮紑涓婃父椋庢帶骞朵繚鐣欏師濮嬪煙鍚嶈В鏋?(Remote DNS)锛岃鎵嬪姩灏嗗崗璁敼涓?socks5h://", - "validation_error": "鍚敤涓婃父浠g悊鏃跺繀椤诲~鍐欎唬鐞嗗湴鍧€", - "restart_hint": "浠g悊閰嶇疆宸蹭繚瀛橈紝閲嶅惎搴旂敤鍚庣敓鏁? + "title": "全局上游代理 (Global Proxy)", + "desc": "开启后,应用内所有外部请求(API 反代、Token 刷新、配额查询、更新检测)都将通过此代理。", + "desc_short": "用于无法匹配代理池账号时的通用出口或降级方案。", + "enable": "启用上游代理", + "url": "代理地址", + "url_placeholder": "例如: http://127.0.0.1:7890 或 socks5://127.0.0.1:7890", + "tip": "支持 HTTP、HTTPS 和 SOCKS5 协议。", + "socks5h_hint": "若需避开上游风控并保留原始域名解析 (Remote DNS),请手动将协议改为 socks5h://", + "validation_error": "启用上游代理时必须填写代理地址", + "restart_hint": "代理配置已保存,重启应用后生效" }, "scheduling": { - "title": "璐﹀彿杞崲涓庝細璇濊皟搴?, - "title_tooltip": "鎺у埗浼氳瘽濡備綍缁戝畾鍒拌处鍙凤紝浠ュ強瑙﹀彂闄愭祦鏃剁殑琛屼负銆?, - "subtitle": "閽堝鍏ㄥ崗璁鎴风浼樺寲 Prompt Caching 鍜岄檺娴佸鐞?(OpenAI/Gemini/Claude)銆?, - "mode": "璋冨害妯″紡", - "mode_tooltip": "缂撳瓨浼樺厛锛氱粦瀹氳处鍙凤紝闄愭祦鏃跺己鍒剁瓑寰咃紙鏈€澶у寲缂撳瓨锛夛紱骞宠 锛氱粦瀹氳处鍙凤紝闄愭祦鏃惰嚜鍔ㄧ儹鍒囷紱鎬ц兘浼樺厛锛氫笉缁戝畾锛屽叏鑷姩杞崲銆?, + "title": "账号轮换与会话调度", + "title_tooltip": "控制会话如何绑定到账号,以及触发限流时的行为。", + "subtitle": "针对全协议客户端优化 Prompt Caching 和限流处理 (OpenAI/Gemini/Claude)。", + "mode": "调度模式", + "mode_tooltip": "缓存优先:绑定账号,限流时强制等待(最大化缓存);平衡:绑定账号,限流时自动热切;性能优先:不绑定,全自动轮换。", "modes": { - "CacheFirst": "缂撳瓨浼樺厛 (Cache First)", - "Balance": "骞宠 杞崲 (Balance)", - "PerformanceFirst": "鎬ц兘浼樺厛 (Performance)" + "CacheFirst": "缓存优先 (Cache First)", + "Balance": "平衡轮换 (Balance)", + "PerformanceFirst": "性能优先 (Performance)" }, "modes_desc": { - "CacheFirst": "缁戝畾浼氳瘽涓庤处鍙凤紝闄愭祦鏃剁簿鍑嗙瓑寰咃紙鏈€澶у寲 Prompt Cache 鍛戒腑鐜囷級銆?, - "Balance": "缁戝畾浼氳瘽锛岄檺娴佹椂鑷姩鐑垏鎹㈣嚦鍙敤璐﹀彿锛堝吋椤剧紦瀛樹笌鍙敤鎬э級銆?, - "PerformanceFirst": "鏃犱細璇濈粦瀹氾紝绾殢鏈鸿疆鎹紙閫傚悎楂樺苟鍙戯紝涓嶈€冭檻缂撳瓨锛夈€? + "CacheFirst": "绑定会话与账号,限流时精准等待(最大化 Prompt Cache 命中率)。", + "Balance": "绑定会话,限流时自动热切换至可用账号(兼顾缓存与可用性)。", + "PerformanceFirst": "无会话绑定,纯随机轮换(适合高并发,不考虑缓存)。" }, - "max_wait": "鏈€澶х瓑寰呮椂闀?(绉?", - "max_wait_tooltip": "浠呭湪鈥滅紦瀛樹紭鍏堚€濇ā寮忎笅鐢熸晥锛氬鏋滆处鍙烽檺娴侀噸缃椂闂村皬浜庢鍊硷紝鍒欏師鍦扮瓑寰呰€岄潪鍒囨崲璐﹀彿銆?, - "clear_bindings": "娓呴櫎浼氳瘽缁戝畾", - "clear_bindings_tooltip": "绔嬪嵆鏂紑鎵€鏈変細璇濅笌璐﹀彿鐨勭粦瀹氬叧绯伙紝寮哄埗涓嬩竴娆¤姹傞噸鏂板垎閰嶈处鍙枫€?, - "clear_rate_limits": "娓呴櫎闄愭祦璁板綍", - "clear_rate_limits_tooltip": "绔嬪嵆娓呴櫎鎵€鏈夎处鍙风殑鏈湴闄愭祦璁板綍锛屽己鍒朵笅涓€娆¤姹傚皾璇曠洿鎺ヨ皟鐢ㄤ笂娓搞€? + "max_wait": "最大等待时长 (秒)", + "max_wait_tooltip": "仅在“缓存优先”模式下生效:如果账号限流重置时间小于此值,则原地等待而非切换账号。", + "clear_bindings": "清除会话绑定", + "clear_bindings_tooltip": "立即断开所有会话与账号的绑定关系,强制下一次请求重新分配账号。", + "clear_rate_limits": "清除限流记录", + "clear_rate_limits_tooltip": "立即清除所有账号的本地限流记录,强制下一次请求尝试直接调用上游。" }, "circuit_breaker": { - "title": "鑷€傚簲鐔旀柇鍣?, - "tooltip": "褰撹处鍙峰洜閰嶉鑰楀敖鍙嶅澶辫触鏃讹紝鑷姩澧炲姞閿佸畾鏃堕棿銆傝繖鍙互闃叉鍦ㄦ璐﹀彿涓婃氮璐?API 璋冪敤锛屽悓鏃跺厑璁哥灛鎬侀敊璇揩閫熸仮澶嶃€?, - "backoff_levels": "閫€閬跨瓑绾?(绉?", - "input_placeholder": "杈撳叆閫€閬挎椂闀?(绉?锛屼互閫楀彿鍒嗛殧", - "level": "绛夌骇 {{level}}", - "invalid_format": "鏍煎紡鏃犳晥銆傝浣跨敤閫楀彿鍒嗛殧鐨勬暟瀛?(渚嬪 60, 300)", - "clear_records": "娓呴櫎鎵€鏈夐檺娴佽褰? + "title": "自适应熔断器", + "tooltip": "当账号因配额耗尽反复失败时,自动增加锁定时间。这可以防止在死账号上浪费 API 调用,同时允许瞬态错误快速恢复。", + "backoff_levels": "退避等级 (秒)", + "input_placeholder": "输入退避时长 (秒),以逗号分隔", + "level": "等级 {{level}}", + "invalid_format": "格式无效。请使用逗号分隔的数字 (例如 60, 300)", + "clear_records": "清除所有限流记录" }, "experimental": { - "title": "瀹為獙鎬ц缃?(Experimental)", - "title_tooltip": "鎺㈢储鎬у姛鑳斤紝鍙兘鍦ㄦ湭鏉ョ増鏈腑璋冩暣鎴栫Щ闄ゃ€?, - "enable_usage_scaling": "鍚敤鐢ㄩ噺缂╂斁", - "enable_usage_scaling_tooltip": "閽堝 Claude 鍏煎鍗忚銆傚綋鎬昏緭鍏ヨ秴杩?30k Token 鏃跺紑鍚縺杩涚缉鏀撅紝闃叉鍦ㄥぇ涓婁笅鏂囦笅棰戠箒瑙﹀彂瀹㈡埛绔帇缂┿€傛敞鎰忥細寮€鍚悗瀹㈡埛绔樉绀虹殑鐢ㄩ噺涓嶅啀浠h〃瀹為檯璁¤垂鐐规暟銆?, - "context_compression_threshold_l1": "L1 鍘嬬缉闃堝€?(宸ュ叿璁板綍娓呯悊)", - "context_compression_threshold_l1_tooltip": "娓呯悊鏃х殑宸ュ叿璋冪敤璁板綍浠ヨ妭鐪佺┖闂淬€傚缓璁€? 0.4 (40%)", - "context_compression_threshold_l2": "L2 鍘嬬缉闃堝€?(鎬濈淮閾惧帇缂?", - "context_compression_threshold_l2_tooltip": "鍘嬬缉鏃╂湡鐨勬€濈淮閾惧唴瀹癸紝淇濈暀绛惧悕銆傚缓璁€? 0.55 (55%)", - "context_compression_threshold_l3": "L3 鍘嬬缉闃堝€?(鎽樿閲嶇疆)", - "context_compression_threshold_l3_tooltip": "寮哄埗鐢熸垚 XML 鐘舵€佹憳瑕佸苟閲嶇疆浼氳瘽銆傝繖鏄渶鐪?token 鐨勬墜娈点€傚缓璁€? 0.7 (70%)" + "title": "实验性设置 (Experimental)", + "title_tooltip": "探索性功能,可能在未来版本中调整或移除。", + "enable_usage_scaling": "启用用量缩放", + "enable_usage_scaling_tooltip": "针对 Claude 兼容协议。当总输入超过 30k Token 时开启激进缩放,防止在大上下文下频繁触发客户端压缩。注意:开启后客户端显示的用量不再代表实际计费点数。", + "context_compression_threshold_l1": "L1 压缩阈值 (工具记录清理)", + "context_compression_threshold_l1_tooltip": "清理旧的工具调用记录以节省空间。建议值: 0.4 (40%)", + "context_compression_threshold_l2": "L2 压缩阈值 (思维链压缩)", + "context_compression_threshold_l2_tooltip": "压缩早期的思维链内容,保留签名。建议值: 0.55 (55%)", + "context_compression_threshold_l3": "L3 压缩阈值 (摘要重置)", + "context_compression_threshold_l3_tooltip": "强制生成 XML 状态摘要并重置会话。这是最省 token 的手段。建议值: 0.7 (70%)" }, "opencode_sync": { "card_title": "OpenCode", "status": { - "detecting": "妫€娴嬩腑...", - "installed": "宸插畨瑁?({{version}})", - "not_installed": "鏈畨瑁?, - "synced": "宸插悓姝?, - "not_synced": "鏈悓姝?, - "current_base_url": "褰撳墠鎺ュ彛鍦板潃 (BASE URL)" + "detecting": "检测中...", + "installed": "已安装 ({{version}})", + "not_installed": "未安装", + "synced": "已同步", + "not_synced": "未同步", + "current_base_url": "当前接口地址 (BASE URL)" }, - "sync_accounts": "鍚屾璐﹀彿鍒?antigravity-accounts.json", - "btn_sync": "绔嬪嵆鍚屾閰嶇疆", - "btn_view": "鏌ョ湅閰嶇疆", - "btn_restore": "杩樺師閰嶇疆", - "btn_restore_backup": "浠庡浠借繕鍘?, - "btn_clear": "娓呴櫎閰嶇疆", - "clear_confirm_title": "纭娓呴櫎閰嶇疆", - "clear_confirm_message": "纭畾瑕佹竻闄?OpenCode 閰嶇疆鍚楋紵杩欏皢鍒犻櫎閰嶇疆鏂囦欢銆?, + "sync_accounts": "同步账号到 antigravity-accounts.json", + "btn_sync": "立即同步配置", + "btn_view": "查看配置", + "btn_restore": "还原配置", + "btn_restore_backup": "从备份还原", + "btn_clear": "清除配置", + "clear_confirm_title": "确认清除配置", + "clear_confirm_message": "确定要清除 OpenCode 配置吗?这将删除配置文件。", "toast": { - "config_missing": "璇峰厛鐢熸垚 API Key 骞跺惎鍔ㄦ湇鍔?, - "sync_success": "OpenCode 閰嶇疆鍚屾鎴愬姛", - "sync_error": "OpenCode 鍚屾澶辫触: {{error}}", - "clear_success": "OpenCode 閰嶇疆宸叉竻闄?, - "clear_error": "娓呴櫎 OpenCode 閰嶇疆澶辫触: {{error}}" + "config_missing": "请先生成 API Key 并启动服务", + "sync_success": "OpenCode 配置同步成功", + "sync_error": "OpenCode 同步失败: {{error}}", + "clear_success": "OpenCode 配置已清除", + "clear_error": "清除 OpenCode 配置失败: {{error}}" }, "modal": { - "view_title": "OpenCode 閰嶇疆鏂囦欢棰勮", - "copy_success": "閰嶇疆宸插鍒? + "view_title": "OpenCode 配置文件预览", + "copy_success": "配置已复制" }, - "sync_confirm_title": "纭鍚屾", - "sync_confirm_message": "灏嗘牴鎹綋鍓嶅弽浠h缃鐩?OpenCode 閰嶇疆銆傜‘瀹氱户缁紵", - "restore_confirm": "纭畾瑕佸皢 OpenCode 杩樺師涓洪粯璁ら厤缃悧锛?, - "restore_backup_confirm": "纭畾瑕佷粠澶囦唤杩樺師 OpenCode 閰嶇疆鍚楋紵", - "modal_title": "閫夋嫨 OpenCode 妯″瀷", - "select_models": "閫夋嫨瑕佸悓姝ョ殑妯″瀷", - "auth_plugin_warning": "妫€娴嬪埌 opencode-antigravity-auth 鎻掍欢銆傚悓姝ヤ粎浼氬垱寤?antigravity-manager provider锛屼笉浼氳鐩?google provider/plugin銆?, - "btn_confirm_sync": "纭鍚屾", - "custom_base_url_label": "鑷畾涔?Manager BaseURL", - "custom_base_url_desc": "閫傜敤浜?Docker Compose 缃戠粶鐜", - "custom_base_url_reset": "閲嶇疆" + "sync_confirm_title": "确认同步", + "sync_confirm_message": "将根据当前反代设置覆盖 OpenCode 配置。确定继续?", + "restore_confirm": "确定要将 OpenCode 还原为默认配置吗?", + "restore_backup_confirm": "确定要从备份还原 OpenCode 配置吗?", + "modal_title": "选择 OpenCode 模型", + "select_models": "选择要同步的模型", + "auth_plugin_warning": "检测到 opencode-antigravity-auth 插件。同步仅会创建 antigravity-manager provider,不会覆盖 google provider/plugin。", + "btn_confirm_sync": "确认同步", + "custom_base_url_label": "自定义 Manager BaseURL", + "custom_base_url_desc": "适用于 Docker Compose 网络环境", + "custom_base_url_reset": "重置" }, "droid_sync": { - "modal_title": "娣诲姞妯″瀷鍒?Droid", - "modal_desc": "閫変腑鐨勬ā鍨嬪皢浣滀负 customModels 鍐欏叆 settings.json", - "selected": "宸查€?, - "btn_confirm_sync": "娣诲姞鎵€閫夋ā鍨?, + "modal_title": "添加模型到 Droid", + "modal_desc": "选中的模型将作为 customModels 写入 settings.json", + "selected": "已选", + "btn_confirm_sync": "添加所选模型", "toast": { - "no_models_selected": "璇疯嚦灏戦€夋嫨涓€涓ā鍨?, - "sync_success_count": "宸叉坊鍔?{{count}} 涓ā鍨嬪埌 Droid", - "sync_error": "鍚屾澶辫触: {{error}}" + "no_models_selected": "请至少选择一个模型", + "sync_success_count": "已添加 {{count}} 个模型到 Droid", + "sync_error": "同步失败: {{error}}" } } }, "cloudflared": { - "title": "鍏綉璁块棶 (Cloudflared)", - "subtitle": "閫氳繃 Cloudflare 闅ч亾灏嗘湰鍦版湇鍔℃毚闇插埌鍏綉", - "not_installed": "Cloudflared 鏈畨瑁?, - "install_hint": "Cloudflared 鏄?Cloudflare 鎻愪緵鐨勫厤璐归毀閬撳伐鍏?鍙皢鏈湴鍙嶄唬鏈嶅姟鏆撮湶鍒板叕缃?鏃犻渶鍏綉IP鎴栫鍙f槧灏勩€傜偣鍑讳笅鏂规寜閽竴閿笅杞藉畨瑁呫€?, - "install": "涓€閿畨瑁?, - "installing": "瀹夎涓?..", - "install_success": "Cloudflared 瀹夎鎴愬姛", - "install_failed": "瀹夎澶辫触: {{error}}", - "installed": "宸插畨瑁?, - "version": "鐗堟湰", - "mode_label": "闅ч亾妯″紡", - "mode_quick": "蹇€熼毀閬?, - "mode_quick_desc": "鑷姩鐢熸垚涓存椂 URL (*.trycloudflare.com),鏃犻渶璐﹀彿,閲嶅惎鍚嶶RL浼氬彉鍖?, - "mode_auth": "鍛藉悕闅ч亾", - "mode_auth_desc": "浣跨敤 Cloudflare 璐﹀彿 Token,鏀寔鑷畾涔夊煙鍚?URL鍥哄畾涓嶅彉", - "token": "闅ч亾 Token", - "token_placeholder": "绮樿创鎮ㄧ殑 Cloudflare Tunnel Token", - "token_hint": "浠?Cloudflare Zero Trust 鎺у埗鍙拌幏鍙?, - "token_required": "鍛藉悕闅ч亾妯″紡闇€瑕佹彁渚?Token", - "use_http2": "浣跨敤 HTTP/2", - "use_http2_desc": "鍏煎鎬ф洿濂?鎺ㄨ崘涓浗澶ч檰鐢ㄦ埛寮€鍚?, - "status_label": "闅ч亾鐘舵€?, - "status_stopped": "鏈繍琛?, - "status_starting": "鍚姩涓?..", - "status_running": "杩愯涓?, - "status_stopping": "鍋滄涓?..", - "status_error": "閿欒", - "public_url": "鍏綉鍦板潃", - "public_url_placeholder": "闅ч亾鍚姩鍚庡皢鏄剧ず鍏綉璁块棶鍦板潃", - "copy_url": "澶嶅埗鍦板潃", - "url_copied": "鍦板潃宸插鍒?, - "start_tunnel": "鍚姩闅ч亾", - "stop_tunnel": "鍋滄闅ч亾", - "running": "闅ч亾杩愯涓?, - "started": "闅ч亾宸插惎鍔?, - "stopped": "闅ч亾宸插仠姝?, - "start_failed": "鍚姩澶辫触: {{error}}", - "stop_failed": "鍋滄澶辫触: {{error}}", - "require_proxy_running": "璇峰厛鍚姩鏈湴鍙嶄唬鏈嶅姟,鍐嶅紑鍚毀閬?, - "connection_info": "杩炴帴淇℃伅", - "local_port": "鏈湴绔彛", - "tunnel_protocol": "闅ч亾鍗忚" + "title": "公网访问 (Cloudflared)", + "subtitle": "通过 Cloudflare 隧道将本地服务暴露到公网", + "not_installed": "Cloudflared 未安装", + "install_hint": "Cloudflared 是 Cloudflare 提供的免费隧道工具,可将本地反代服务暴露到公网,无需公网IP或端口映射。点击下方按钮一键下载安装。", + "install": "一键安装", + "installing": "安装中...", + "install_success": "Cloudflared 安装成功", + "install_failed": "安装失败: {{error}}", + "installed": "已安装", + "version": "版本", + "mode_label": "隧道模式", + "mode_quick": "快速隧道", + "mode_quick_desc": "自动生成临时 URL (*.trycloudflare.com),无需账号,重启后URL会变化", + "mode_auth": "命名隧道", + "mode_auth_desc": "使用 Cloudflare 账号 Token,支持自定义域名,URL固定不变", + "token": "隧道 Token", + "token_placeholder": "粘贴您的 Cloudflare Tunnel Token", + "token_hint": "从 Cloudflare Zero Trust 控制台获取", + "token_required": "命名隧道模式需要提供 Token", + "use_http2": "使用 HTTP/2", + "use_http2_desc": "兼容性更好,推荐中国大陆用户开启", + "status_label": "隧道状态", + "status_stopped": "未运行", + "status_starting": "启动中...", + "status_running": "运行中", + "status_stopping": "停止中...", + "status_error": "错误", + "public_url": "公网地址", + "public_url_placeholder": "隧道启动后将显示公网访问地址", + "copy_url": "复制地址", + "url_copied": "地址已复制", + "start_tunnel": "启动隧道", + "stop_tunnel": "停止隧道", + "running": "隧道运行中", + "started": "隧道已启动", + "stopped": "隧道已停止", + "start_failed": "启动失败: {{error}}", + "stop_failed": "停止失败: {{error}}", + "require_proxy_running": "请先启动本地反代服务,再开启隧道", + "connection_info": "连接信息", + "local_port": "本地端口", + "tunnel_protocol": "隧道协议" }, "example": { - "title": "浣跨敤绀轰緥", + "title": "使用示例", "curl": "cURL", "python": "Python", - "python_anthropic": "from anthropic import Anthropic\n\nclient = Anthropic(\n # 鎺ㄨ崘浣跨敤 127.0.0.1\n base_url=\"{{baseUrl}}\",\n api_key=\"{{apiKey}}\"\n)\n\n# 娉ㄦ剰: Antigravity 鏀寔浣跨敤 Anthropic SDK 璋冪敤浠绘剰妯″瀷\nresponse = client.messages.create(\n model=\"{{modelId}}\",\n max_tokens=1024,\n messages=[{\"role\": \"user\", \"content\": \"Hello\"}]\n)\n\nprint(response.content[0].text)", - "python_gemini": "# 闇€瑕佸畨瑁? pip install google-generativeai\nimport google.generativeai as genai\n\n# 浣跨敤 Antigravity 浠g悊鍦板潃 (鎺ㄨ崘 127.0.0.1)\ngenai.configure(\n api_key=\"{{apiKey}}\",\n transport='rest',\n client_options={'api_endpoint': '{{rawBaseUrl}}'}\n)\n\nmodel = genai.GenerativeModel('{{modelId}}')\nresponse = model.generate_content(\"Hello\")\nprint(response.text)", - "python_openai_image": "from openai import OpenAI\n\nclient = OpenAI(\n base_url=\"{{baseUrl}}\",\n api_key=\"{{apiKey}}\"\n)\n\nresponse = client.chat.completions.create(\n model=\"{{modelId}}\",\n # 鏂瑰紡 1: 浣跨敤 size 鍙傛暟 (鎺ㄨ崘)\n # 鏀寔: \"1024x1024\" (1:1), \"1280x720\" (16:9), \"720x1280\" (9:16), \"1216x896\" (4:3)\n extra_body={ \"size\": \"1024x1024\" },\n\n # 鏂瑰紡 2: 浣跨敤妯″瀷鍚庣紑\n # 渚嬪: gemini-3-pro-image-16-9, gemini-3-pro-image-4-3\n # model=\"gemini-3-pro-image-16-9\",\n messages=[{\n \"role\": \"user\",\n \"content\": \"鐢讳竴涓湭鏉ュ煄甯俓"\n }]\n)\n\nprint(response.choices[0].message.content)", + "python_anthropic": "from anthropic import Anthropic\n\nclient = Anthropic(\n # 推荐使用 127.0.0.1\n base_url=\"{{baseUrl}}\",\n api_key=\"{{apiKey}}\"\n)\n\n# 注意: Antigravity 支持使用 Anthropic SDK 调用任意模型\nresponse = client.messages.create(\n model=\"{{modelId}}\",\n max_tokens=1024,\n messages=[{\"role\": \"user\", \"content\": \"Hello\"}]\n)\n\nprint(response.content[0].text)", + "python_gemini": "# 需要安装: pip install google-generativeai\nimport google.generativeai as genai\n\n# 使用 Antigravity 代理地址 (推荐 127.0.0.1)\ngenai.configure(\n api_key=\"{{apiKey}}\",\n transport='rest',\n client_options={'api_endpoint': '{{rawBaseUrl}}'}\n)\n\nmodel = genai.GenerativeModel('{{modelId}}')\nresponse = model.generate_content(\"Hello\")\nprint(response.text)", + "python_openai_image": "from openai import OpenAI\n\nclient = OpenAI(\n base_url=\"{{baseUrl}}\",\n api_key=\"{{apiKey}}\"\n)\n\nresponse = client.chat.completions.create(\n model=\"{{modelId}}\",\n # 方式 1: 使用 size 参数 (推荐)\n # 支持: \"1024x1024\" (1:1), \"1280x720\" (16:9), \"720x1280\" (9:16), \"1216x896\" (4:3)\n extra_body={ \"size\": \"1024x1024\" },\n\n # 方式 2: 使用模型后缀\n # 例如: gemini-3-pro-image-16-9, gemini-3-pro-image-4-3\n # model=\"gemini-3-pro-image-16-9\",\n messages=[{\n \"role\": \"user\",\n \"content\": \"画一个未来城市\"\n }]\n)\n\nprint(response.choices[0].message.content)", "python_openai": "from openai import OpenAI\n\nclient = OpenAI(\n base_url=\"{{baseUrl}}\",\n api_key=\"{{apiKey}}\"\n)\n\nresponse = client.chat.completions.create(\n model=\"{{modelId}}\",\n messages=[{\"role\": \"user\", \"content\": \"Hello\"}]\n)\n\nprint(response.choices[0].message.content)" }, "dialog": { - "confirm_regenerate": "纭畾瑕佺敓鎴愭柊鐨?API Key 鍚楋紵鏃х殑 Key 灏嗙珛鍗冲け鏁堛€?, - "operate_failed": "鎿嶄綔澶辫触: {{error}}", - "reset_mapping_title": "閲嶇疆妯″瀷鏄犲皠", - "reset_mapping_msg": "纭畾瑕侀噸缃墍鏈夋ā鍨嬫槧灏勪负绯荤粺榛樿鍚楋紵姝ゆ搷浣滄棤娉曟挙閿€銆?, - "regenerate_key_title": "閲嶆柊鐢熸垚 API Key", - "regenerate_key_msg": "纭畾瑕侀噸鏂扮敓鎴?API Key 鍚楋紵鏃х殑 Key 灏嗙珛鍗冲け鏁堛€?, - "clear_bindings_title": "娓呴櫎浼氳瘽缁戝畾", - "clear_bindings_msg": "纭畾瑕佹竻闄ゆ墍鏈変細璇濅笌璐﹀彿鐨勭粦瀹氭槧灏勫悧锛?, - "clear_rate_limits_title": "娓呴櫎闄愭祦璁板綍", - "clear_rate_limits_confirm": "纭畾瑕佹竻闄ゆ墍鏈夋湰鍦伴檺娴佽褰曞悧锛? + "confirm_regenerate": "确定要生成新的 API Key 吗?旧的 Key 将立即失效。", + "operate_failed": "操作失败: {{error}}", + "reset_mapping_title": "重置模型映射", + "reset_mapping_msg": "确定要重置所有模型映射为系统默认吗?此操作无法撤销。", + "regenerate_key_title": "重新生成 API Key", + "regenerate_key_msg": "确定要重新生成 API Key 吗?旧的 Key 将立即失效。", + "clear_bindings_title": "清除会话绑定", + "clear_bindings_msg": "确定要清除所有会话与账号的绑定映射吗?", + "clear_rate_limits_title": "清除限流记录", + "clear_rate_limits_confirm": "确定要清除所有本地限流记录吗?" }, "model": { - "flash": "鏋侀€熷搷搴?, - "flash_preview": "鏋侀€熼瑙?(Flash 3.1)", - "flash_lite": "杞婚噺鏋侀€?(Lite)", - "flash_thinking": "鎬濊€冭兘鍔?(Thinking)", - "pro_legacy": "缁忓吀鐗?Pro", + "flash": "极速响应", + "flash_preview": "极速预览 (Flash 3.1)", + "flash_lite": "轻量极速 (Lite)", + "flash_thinking": "思考能力 (Thinking)", + "pro_legacy": "经典版 Pro", "pro_low": "3.1 Pro Low", "pro_high": "3.1 Pro High", - "pro_image": "鍥剧墖鐢熸垚 (1:1)", - "pro_image_16_9": "鍥剧墖鐢熸垚 (16:9)", - "pro_image_9_16": "鍥剧墖鐢熸垚 (9:16)", - "pro_image_4_3": "鍥剧墖鐢熸垚 (4:3)", - "pro_image_3_4": "鍥剧墖鐢熸垚 (3:4)", - "pro_image_1_1": "鍥剧墖鐢熸垚 (1:1)", - "claude_sonnet": "浠g爜鎺ㄧ悊 (Claude 4.6)", - "claude_sonnet_thinking": "鎬濈淮閾?(4.6 Think)", - "claude_opus_thinking": "鏈€寮烘€濈淮 (Opus Think)", - "gemini_2_5_flash": "鏋侀€熸ā鍨?(2.5 Flash)", - "gemini_2_5_pro": "楂樻€ц兘鎺ㄧ悊 (2.5 Pro)", - "claude_4_6": "鏈€鏂颁唬鐞嗙増 (4.6)" + "pro_image": "图片生成 (1:1)", + "pro_image_16_9": "图片生成 (16:9)", + "pro_image_9_16": "图片生成 (9:16)", + "pro_image_4_3": "图片生成 (4:3)", + "pro_image_3_4": "图片生成 (3:4)", + "pro_image_1_1": "图片生成 (1:1)", + "claude_sonnet": "代码推理 (Claude 4.6)", + "claude_sonnet_thinking": "思维链 (4.6 Think)", + "claude_opus_thinking": "最强思维 (Opus Think)", + "gemini_2_5_flash": "极速模型 (2.5 Flash)", + "gemini_2_5_pro": "高性能推理 (2.5 Pro)", + "claude_4_6": "最新代理版 (4.6)" }, "mapping": { - "title": "Claude Code 妯″瀷鏄犲皠", - "description": "灏?Claude Code 妯″瀷鏄犲皠鍒?Antigravity 妯″瀷,鏅鸿兘璺敱璇锋眰浠ヤ紭鍖栨垚鏈拰閫熷害銆?, - "default": "榛樿", - "sonnet_desc": "鏈€寮哄鏉備换鍔?, - "opus_desc": "楂樼骇灞傜骇", - "haiku_desc": "鏋侀€熷搷搴?, - "maps_to": "鏄犲皠鍒?Antigravity", - "apply_recommended": "搴旂敤鎺ㄨ崘閰嶇疆", - "restore_defaults": "鎭㈠榛樿閰嶇疆", - "reset_all": "閲嶇疆鍏ㄩ儴" + "title": "Claude Code 模型映射", + "description": "将 Claude Code 模型映射到 Antigravity 模型,智能路由请求以优化成本和速度。", + "default": "默认", + "sonnet_desc": "最强复杂任务", + "opus_desc": "高级层级", + "haiku_desc": "极速响应", + "maps_to": "映射到 Antigravity", + "apply_recommended": "应用推荐配置", + "restore_defaults": "恢复默认配置", + "reset_all": "重置全部" }, "models": { - "flash": "鏋侀€熷搷搴?, - "flash_thinking": "鎬濊€冭兘鍔?, - "pro_high": "鏈€寮烘帹鐞?, - "pro_low": "浣庨厤棰?, - "sonnet": "浠g爜鎺ㄧ悊", - "sonnet_thinking": "鎬濈淮閾?, - "opus_thinking": "鏈€寮烘€濈淮" + "flash": "极速响应", + "flash_thinking": "思考能力", + "pro_high": "最强推理", + "pro_low": "低配额", + "sonnet": "代码推理", + "sonnet_thinking": "思维链", + "opus_thinking": "最强思维" }, "router": { - "title": "妯″瀷璺敱涓績 (Model Router)", - "subtitle": "鎸夆€滆鏍煎鏃忊€濈粺涓€璺敱 OpenAI/Claude 妯″瀷锛屾垨娣诲姞鏈€楂樹紭鍏堢骇鐨勨€滅簿纭槧灏勨€濄€俓n娉ㄦ剰锛欳laude 鍘熺敓鐩撮€氭ā鍨嬶紙claude-sonnet-4-6-thinking, claude-opus-4-6-thinking 绛夛級榛樿閫忎紶锛岄渶鍦ㄢ€滀笓瀹剁簿纭槧灏勨€濅腑娣诲姞瑙勫垯鎵嶈兘淇敼銆?, - "subtitle_simple": "閫氳繃閫氶厤绗︽垨绮剧‘鏄犲皠鑷畾涔夋ā鍨嬭矾鐢辫鍒?, - "background_task_title": "鍚庡彴浠诲姟妯″瀷", - "background_task_desc": "鐢ㄤ簬 Claude CLI 鐨勬爣棰樼敓鎴愩€佹憳瑕佹彁鍙栫瓑鍚庡彴鑷姩鍖栦换鍔?(榛樿: gemini-2.5-flash)", - "use_default": "浣跨敤绯荤粺榛樿", - "current_model": "褰撳墠妯″瀷", - "apply_presets": "搴旂敤棰勮鏄犲皠", - "presets_applied": "棰勮鏄犲皠宸插簲鐢?, - "preset_default": "榛樿棰勮", - "preset_default_desc": "GPT-4 鈫?Gemini Pro, Claude 鈫?Opus", - "preset_performance": "鎬ц兘浼樺厛", - "preset_performance_desc": "鍏ㄩ儴浣跨敤楂樻€ц兘妯″瀷", - "preset_cost": "鎴愭湰浼樺寲", - "preset_cost_desc": "浼樺厛浣跨敤缁忔祹鍨嬫ā鍨?, - "preset_balanced": "鍧囪 妯″紡", - "preset_balanced_desc": "骞宠 鎬ц兘鍜屾垚鏈?, - "built_in_presets": "鍐呯疆棰勮", - "custom_presets": "鑷畾涔夐璁?, - "apply_selected": "搴旂敤鎵€閫?, - "add_preset": "淇濆瓨褰撳墠鏄犲皠", - "delete_preset": "鍒犻櫎褰撳墠棰勮", - "cannot_delete_builtin": "鏃犳硶鍒犻櫎鍐呯疆棰勮", - "no_mapping_to_save": "娌℃湁鍙繚瀛樼殑鏄犲皠閰嶇疆", - "preset_name_required": "璇峰厛杈撳叆棰勮鍚嶇О", - "preset_saved": "棰勮淇濆瓨鎴愬姛", - "manage_presets_title": "绠$悊鑷畾涔夐璁?, - "save_current_as_preset": "淇濆瓨褰撳墠閰嶇疆", - "preset_name_placeholder": "杈撳叆棰勮鍚嶇О...", - "save_hint": "灏嗗綋鍓嶆縺娲荤殑妯″瀷鏄犲皠淇濆瓨涓哄彲閲嶅浣跨敤鐨勯璁俱€?, - "your_presets": "鎮ㄧ殑棰勮", - "no_custom_presets": "鏆傛棤鑷畾涔夐璁?, - "mappings_count": "涓槧灏?, - "custom_preset_desc": "鐢ㄦ埛鑷畾涔夐璁?, - "custom_mappings": "鑷畾涔夋槧灏?(Custom Mappings)", - "original_id": "鍘熷妯″瀷 ID", - "route_to": "璺敱鐩爣", - "group_title": "妯″瀷瀹舵棌鍒嗙粍 (Series Groups)", - "gemini3_group_label": "Gemini 3 (鎺ㄨ崘)", - "gemini3_option_high": "gemini-3.1-pro-high (楂樿川閲?", - "gemini3_option_low": "gemini-3.1-pro-low (鍧囪 )", - "gemini3_option_flash": "gemini-3-flash (蹇€?", + "title": "模型路由中心 (Model Router)", + "subtitle": "按“规格家族”统一路由 OpenAI/Claude 模型,或添加最高优先级的“精确映射”。\n注意:Claude 原生直通模型(claude-sonnet-4-6-thinking, claude-opus-4-6-thinking 等)默认透传,需在“专家精确映射”中添加规则才能修改。", + "subtitle_simple": "通过通配符或精确映射自定义模型路由规则", + "background_task_title": "后台任务模型", + "background_task_desc": "用于 Claude CLI 的标题生成、摘要提取等后台自动化任务 (默认: gemini-2.5-flash)", + "use_default": "使用系统默认", + "current_model": "当前模型", + "apply_presets": "应用预设映射", + "presets_applied": "预设映射已应用", + "preset_default": "默认预设", + "preset_default_desc": "GPT-4 → Gemini Pro, Claude → Opus", + "preset_performance": "性能优先", + "preset_performance_desc": "全部使用高性能模型", + "preset_cost": "成本优化", + "preset_cost_desc": "优先使用经济型模型", + "preset_balanced": "均衡模式", + "preset_balanced_desc": "平衡性能和成本", + "built_in_presets": "内置预设", + "custom_presets": "自定义预设", + "apply_selected": "应用所选", + "add_preset": "保存当前映射", + "delete_preset": "删除当前预设", + "cannot_delete_builtin": "无法删除内置预设", + "no_mapping_to_save": "没有可保存的映射配置", + "preset_name_required": "请先输入预设名称", + "preset_saved": "预设保存成功", + "manage_presets_title": "管理自定义预设", + "save_current_as_preset": "保存当前配置", + "preset_name_placeholder": "输入预设名称...", + "save_hint": "将当前激活的模型映射保存为可重复使用的预设。", + "your_presets": "您的预设", + "no_custom_presets": "暂无自定义预设", + "mappings_count": "个映射", + "custom_preset_desc": "用户自定义预设", + "custom_mappings": "自定义映射 (Custom Mappings)", + "original_id": "原始模型 ID", + "route_to": "路由目标", + "group_title": "模型家族分组 (Series Groups)", + "gemini3_group_label": "Gemini 3 (推荐)", + "gemini3_option_high": "gemini-3.1-pro-high (高质量)", + "gemini3_option_low": "gemini-3.1-pro-low (均衡)", + "gemini3_option_flash": "gemini-3-flash (快速)", "groups": { "claude_45": { - "name": "Opus 4.6 TK 绯诲垪", - "desc": "Opus 4.5 TK (鎺ㄧ悊)" + "name": "Opus 4.6 TK 系列", + "desc": "Opus 4.5 TK (推理)" }, "claude_35": { - "name": "Claude 3.5 绯诲垪", + "name": "Claude 3.5 系列", "desc": "Sonnet 3.5, Haiku 3.5" }, "gpt_4": { - "name": "GPT-4 / o1 绯诲垪", + "name": "GPT-4 / o1 系列", "desc": "GPT-4, Turbo, o1-preview" }, "gpt_4o": { - "name": "GPT-4o / 3.5 绯诲垪", + "name": "GPT-4o / 3.5 系列", "desc": "GPT-4o, Mini, 3.5 Turbo" }, "gpt_5": { - "name": "GPT-5 绯诲垪", + "name": "GPT-5 系列", "desc": "GPT-5.1, GPT-5.2 xhigh" } }, - "expert_title": "涓撳绮剧‘鏄犲皠", - "expert_subtitle": "绮剧‘鍖归厤鏀寔浠庝换浣曞崗璁紶鏉ョ殑鍘熷妯″瀷 ID銆?, - "custom_mapping_tip": "馃挕 鏀寔鎵嬪姩杈撳叆浠绘剰妯″瀷 ID,鍙綋楠屾湭鍙戝竷妯″瀷(濡?claude-opus-4-6)銆?, - "custom_mapping_warning": "娉ㄦ剰:骞堕潪鎵€鏈夎处鍙烽兘鏀寔鏈彂甯冩ā鍨嬨€?, - "money_saving_tip": "馃挵 鐪侀挶鎻愮ず:", - "haiku_optimization_tip": "Claude CLI 榛樿浣跨敤 {{model}} 澶勭悊鍚庡彴浠诲姟,寤鸿鏄犲皠鍒板粔浠?Flash 妯″瀷鍙妭鐪佺害 95% 鎴愭湰", - "haiku_optimization_btn": "涓€閿紭鍖?, - "haiku_tip_title": "馃挵 鐪侀挶鎻愮ず:", - "haiku_tip_body_before": "Claude CLI 榛樿浣跨敤", - "haiku_tip_body_after": "澶勭悊鍚庡彴浠诲姟,寤鸿鏄犲皠鍒板粔浠?Flash 妯″瀷鍙妭鐪佺害 95% 鎴愭湰", - "haiku_tip_action": "涓€閿紭鍖?, - "reset_confirm": "纭畾瑕侀噸缃墍鏈夋ā鍨嬫槧灏勪负绯荤粺榛樿鍚楋紵", - "reset_mapping": "閲嶇疆鏄犲皠", - "add_mapping": "娣诲姞鏄犲皠 (Add Mapping)", - "current_list": "褰撳墠鏄犲皠鍒楄〃 (Custom List)", - "no_custom_mapping": "鏆傛棤鑷畾涔夌簿纭槧灏?, - "gemini3_only_warning": "鈿狅笍 浠呮敮鎸?Gemini 3 绯诲垪", - "default_suffix": "锛堥粯璁わ級", - "select_target_model": "閫夋嫨鐩爣妯″瀷", - "original_placeholder": "鍘熷鍚?(濡?gpt-4 鎴?gpt-4*)" + "expert_title": "专家精确映射", + "expert_subtitle": "精确匹配支持从任何协议传来的原始模型 ID。", + "custom_mapping_tip": "💡 支持手动输入任意模型 ID,可体验未发布模型(如 claude-opus-4-6)。", + "custom_mapping_warning": "注意:并非所有账号都支持未发布模型。", + "money_saving_tip": "💰 省钱提示:", + "haiku_optimization_tip": "Claude CLI 默认使用 {{model}} 处理后台任务,建议映射到廉价 Flash 模型可节省约 95% 成本", + "haiku_optimization_btn": "一键优化", + "haiku_tip_title": "💰 省钱提示:", + "haiku_tip_body_before": "Claude CLI 默认使用", + "haiku_tip_body_after": "处理后台任务,建议映射到廉价 Flash 模型可节省约 95% 成本", + "haiku_tip_action": "一键优化", + "reset_confirm": "确定要重置所有模型映射为系统默认吗?", + "reset_mapping": "重置映射", + "add_mapping": "添加映射 (Add Mapping)", + "current_list": "当前映射列表 (Custom List)", + "no_custom_mapping": "暂无自定义精确映射", + "gemini3_only_warning": "⚠️ 仅支持 Gemini 3 系列", + "default_suffix": "(默认)", + "select_target_model": "选择目标模型", + "original_placeholder": "原始名 (如 gpt-4 或 gpt-4*)" }, "examples": { - "title": "浣跨敤绀轰緥" + "title": "使用示例" }, "multi_protocol": { - "title": "澶氬崗璁敮鎸?(Multi-Protocol Support)", - "subtitle": "蹇€熷悓姝?API 鍦板潃涓庡瘑閽ュ埌鏈湴 AI 宸ュ叿", - "description": "鍙嶄唬鏈嶅姟鏀寔 OpenAI銆丄nthropic 鍜?Gemini 鍗忚锛屾弧瓒充笉鍚屽伐鍏风殑闆嗘垚闇€姹?, - "openai_label": "OpenAI 鍗忚", - "anthropic_label": "Anthropic 鍗忚", + "title": "多协议支持 (Multi-Protocol Support)", + "subtitle": "快速同步 API 地址与密钥到本地 AI 工具", + "description": "反代服务支持 OpenAI、Anthropic 和 Gemini 协议,满足不同工具的集成需求", + "openai_label": "OpenAI 协议", + "anthropic_label": "Anthropic 协议", "openai_tools": "Cherry Studio, NextChat", "anthropic_tools": "Claude Code CLI", - "gemini_label": "Gemini 鍗忚", + "gemini_label": "Gemini 协议", "gemini_tools": "Google AI SDK, LangChain", - "quick_integration": "蹇€熼泦鎴?(Quick Integration)", - "click_tip": "馃憜 鐐瑰嚮妯″瀷浠ユ洿鏂颁唬鐮佺ず渚?, - "copy_base": "澶嶅埗 Base" + "quick_integration": "快速集成 (Quick Integration)", + "click_tip": "👆 点击模型以更新代码示例", + "copy_base": "复制 Base" }, "supported_models": { - "title": "鏀寔妯″瀷涓庨泦鎴?(Supported Models & Integration)", - "model_name": "妯″瀷鍚嶇О", - "model_id": "妯″瀷 ID", - "description": "鎻忚堪", - "action": "鎿嶄綔" + "title": "支持模型与集成 (Supported Models & Integration)", + "model_name": "模型名称", + "model_id": "模型 ID", + "description": "描述", + "action": "操作" }, "cli_sync": { - "title": "CLI 閰嶇疆涓€閿悓姝?, - "subtitle": "蹇€熷皢褰撳墠 API 鏈嶅姟鍦板潃涓?API 瀵嗛挜鍚屾鍒版湰鍦?AI CLI 宸ュ叿涓?, - "card_title": "{{name}} 閰嶇疆", + "title": "CLI 配置一键同步", + "subtitle": "快速将当前 API 服务地址与 API 密钥同步到本地 AI CLI 工具中", + "card_title": "{{name}} 配置", "status": { - "not_installed": "鏈娴嬪埌瀹夎", + "not_installed": "未检测到安装", "installed": "v{{version}}", - "synced": "宸叉寚鍚戞湰椤圭洰", - "not_synced": "鏈悓姝?, - "detecting": "妫€娴嬩腑...", - "current_base_url": "褰撳墠鎺ュ彛鍦板潃 (Base URL)" + "synced": "已指向本项目", + "not_synced": "未同步", + "detecting": "检测中...", + "current_base_url": "当前接口地址 (Base URL)" }, - "model_select": "閫夋嫨鍚屾妯″瀷", - "btn_sync": "绔嬪嵆鍚屾閰嶇疆", - "btn_view": "鏌ョ湅褰撳墠閰嶇疆", - "btn_restore": "鎭㈠榛樿閰嶇疆", - "btn_restore_backup": "鎭㈠鍘熸湁閰嶇疆", - "restore_confirm": "纭畾瑕佸皢 {{name}} 鐨勯厤缃仮澶嶄负瀹樻柟榛樿鍦板潃鍚楋紵", - "restore_backup_confirm": "妫€娴嬪埌鏃х殑閰嶇疆鏂囦欢澶囦唤锛岀‘瀹氳杩樺師鍚楋紵", + "model_select": "选择同步模型", + "btn_sync": "立即同步配置", + "btn_view": "查看当前配置", + "btn_restore": "恢复默认配置", + "btn_restore_backup": "恢复原有配置", + "restore_confirm": "确定要将 {{name}} 的配置恢复为官方默认地址吗?", + "restore_backup_confirm": "检测到旧的配置文件备份,确定要还原吗?", "modal": { - "view_title": "{{name}} 閰嶇疆鏂囦欢鍐呭", - "copy_success": "閰嶇疆鍐呭宸插鍒? + "view_title": "{{name}} 配置文件内容", + "copy_success": "配置内容已复制" }, "toast": { - "sync_success": "鍚屾鎴愬姛锛亄{name}} 宸插噯澶囧氨缁€?, - "sync_error": "鍚屾澶辫触锛歿{error}}" + "sync_success": "同步成功!{{name}} 已准备就绪。", + "sync_error": "同步失败:{{error}}" }, - "sync_confirm_title": "鍚屾纭", - "sync_confirm_message": "鍗冲皢涓烘偍鍚屾 {{name}} 鐨勯厤缃€傗殸锔?娉ㄦ剰锛氭鎿嶄綔灏嗚鐩栨偍鏈湴宸叉湁鐨勯厤缃枃浠讹紙濡傜櫥褰曠姸鎬併€丄PI Key 绛夛級銆傜‘瀹氳缁х画鍚楋紵" + "sync_confirm_title": "同步确认", + "sync_confirm_message": "即将为您同步 {{name}} 的配置。⚠️ 注意:此操作将覆盖您本地已有的配置文件(如登录状态、API Key 等)。确定要继续吗?" } }, "monitor": { - "page_title": "API 鐩戞帶鐪嬫澘", - "page_subtitle": "瀹炴椂璇锋眰鏃ュ織涓庡垎鏋?, - "open_monitor": "鎵撳紑鐩戞帶", + "page_title": "API 监控看板", + "page_subtitle": "实时请求日志与分析", + "open_monitor": "打开监控", "logging_status": { - "active": "姝e湪褰曞埗", - "paused": "宸叉殏鍋? + "active": "正在录制", + "paused": "已暂停" }, "stats": { - "total": "鎬昏", - "ok": "姝e父", - "err": "閿欒" + "total": "总计", + "ok": "正常", + "err": "错误" }, "filters": { - "placeholder": "鎼滅储妯″瀷 (gemini, claude)銆佽矾寰?(chat, images) 鎴栫姸鎬佺爜...", - "quick_filters": "蹇€熻繃婊?", - "all": "鍏ㄩ儴", - "error": "浠呴敊璇?, - "chat": "鑱婂ぉ", + "placeholder": "搜索模型 (gemini, claude)、路径 (chat, images) 或状态码...", + "quick_filters": "快速过滤:", + "all": "全部", + "error": "仅错误", + "chat": "聊天", "gemini": "Gemini", "claude": "Claude", - "images": "缁樺浘", - "reset": "閲嶇疆", - "by_account": "鎸夎处鍙风瓫閫?, - "all_accounts": "鍏ㄩ儴璐﹀彿" + "images": "绘图", + "reset": "重置", + "by_account": "按账号筛选", + "all_accounts": "全部账号" }, "table": { - "status": "鐘舵€?, - "method": "鏂规硶", - "model": "妯″瀷", - "protocol": "鍗忚", - "account": "璐﹀彿", - "path": "璺緞", - "usage": "Token 娑堣€?, - "duration": "鑰楁椂", - "time": "鏃堕棿", - "empty": "鏆傛棤璇锋眰璁板綍" + "status": "状态", + "method": "方法", + "model": "模型", + "protocol": "协议", + "account": "账号", + "path": "路径", + "usage": "Token 消耗", + "duration": "耗时", + "time": "时间", + "empty": "暂无请求记录" }, "details": { - "title": "璇锋眰璇︽儏", - "request_payload": "璇锋眰鎶ユ枃 (Request)", - "response_payload": "鍝嶅簲鎶ユ枃 (Response)", - "duration": "鑰楁椂", - "tokens": "Token 娑堣€?(杈撳叆/杈撳嚭)", - "time": "璇锋眰鏃堕棿", - "model": "浣跨敤妯″瀷", - "mapped_model": "鏄犲皠妯″瀷", - "protocol": "璇锋眰鍗忚", - "account_used": "浣跨敤璐﹀彿", - "id": "璇锋眰 ID", - "payload_empty": "鏃犳暟鎹? + "title": "请求详情", + "request_payload": "请求报文 (Request)", + "response_payload": "响应报文 (Response)", + "duration": "耗时", + "tokens": "Token 消耗 (输入/输出)", + "time": "请求时间", + "model": "使用模型", + "mapped_model": "映射模型", + "protocol": "请求协议", + "account_used": "使用账号", + "id": "请求 ID", + "payload_empty": "无数据" }, "dialog": { - "clear_title": "娓呴櫎鐩戞帶鏃ュ織", - "clear_msg": "纭畾瑕佹竻闄ゆ墍鏈夌洃鎺ц褰曞悧锛熸鎿嶄綔鏃犳硶鎾ら攢銆? + "clear_title": "清除监控日志", + "clear_msg": "确定要清除所有监控记录吗?此操作无法撤销。" } }, "update_notification": { - "title": "鍙戠幇鏂扮増鏈?, - "message": "鏂扮増鏈凡鍑嗗灏辩华锛屽寘鍚澶氫紭鍖栦笌鏀硅繘銆傚綋鍓嶇増鏈? v{{current}}", - "ready": "鏇存柊鍑嗗灏辩华", - "downloading": "姝e湪涓嬭浇鏇存柊...", - "restarting": "姝e湪閲嶅惎搴旂敤...", - "auto_update": "鑷姩鏇存柊", + "title": "发现新版本", + "message": "新版本已准备就绪,包含诸多优化与改进。当前版本: v{{current}}", + "ready": "更新准备就绪", + "downloading": "正在下载更新...", + "restarting": "正在重启应用...", + "auto_update": "自动更新", "toast": { - "not_ready": "鑷姩鏇存柊鍖呭皻鏈氨缁紝涓烘偍璺宠浆鍒颁笅杞介〉闈?..", - "failed": "鑷姩鏇存柊澶辫触锛屼负鎮ㄨ烦杞埌涓嬭浇椤甸潰..." + "not_ready": "自动更新包尚未就绪,为您跳转到下载页面...", + "failed": "自动更新失败,为您跳转到下载页面..." } }, "login": { - "title": "瀹夊叏璁块棶鎺у埗", - "desc": "褰撳墠杩愯鍦?Web 妯″紡涓嬶紝璇疯緭鍏ョ鐞嗗瘑鐮佹垨 API Key 浠ヨ繘鍏ュ悗鍙般€?, - "placeholder": "璇疯緭鍏ョ鐞嗗瘑鐮佹垨 API Key", - "btn_login": "楠岃瘉骞惰繘鍏?, - "btn_verifying": "楠岃瘉涓?..", - "error_invalid_key": "瀵嗙爜鎴?API Key 閿欒锛岃閲嶈瘯", - "error_network": "缃戠粶杩炴帴澶辫触锛岃妫€鏌ユ湇鍔℃槸鍚︽甯歌繍琛?, - "note": "娉ㄦ剰锛氬鏋滆缃簡鐙珛鐨勭鐞嗗瘑鐮侊紝璇疯緭鍏ョ鐞嗗瘑鐮侊紱鍚﹀垯璇疯緭鍏?API_KEY銆?, + "title": "安全访问控制", + "desc": "当前运行在 Web 模式下,请输入管理密码或 API Key 以进入后台。", + "placeholder": "请输入管理密码或 API Key", + "btn_login": "验证并进入", + "btn_verifying": "验证中...", + "error_invalid_key": "密码或 API Key 错误,请重试", + "error_network": "网络连接失败,请检查服务是否正常运行", + "note": "注意:如果设置了独立的管理密码,请输入管理密码;否则请输入 API_KEY。", "lookup_hint": "请查看 gui_config.json 或检查环境变量以获取它们。", - "config_hint": "鎴栨墽琛?grep -E '\"api_key\"|\"admin_password\"' ~/.antigravity_tools/gui_config.json 鏌ョ湅銆? + "config_hint": "或执行 grep -E '\"api_key\"|\"admin_password\"' ~/.antigravity_tools/gui_config.json 查看。" }, "token_stats": { - "title": "Token 娑堣垂缁熻", - "hourly": "灏忔椂", - "daily": "鏃?, - "weekly": "鍛?, - "total_tokens": "鎬?Token", - "input_tokens": "杈撳叆 Token", - "output_tokens": "杈撳嚭 Token", - "accounts_used": "娲昏穬璐﹀彿", - "models_used": "浣跨敤妯″瀷", - "model_trend": "鍒嗘ā鍨嬩娇鐢ㄨ秼鍔?, - "account_trend": "鍒嗚处鍙蜂娇鐢ㄨ秼鍔?, - "usage_trend": "Token 浣跨敤瓒嬪娍", - "by_account": "鍒嗚处鍙风粺璁?, - "by_model": "鎸夋ā鍨?, - "by_account_view": "鎸夎处鍙?, - "model_details": "鍒嗘ā鍨嬭缁嗙粺璁?, - "account_details": "璐﹀彿璇︾粏缁熻", - "model": "妯″瀷", - "account": "璐﹀彿", - "requests": "璇锋眰鏁?, - "input": "杈撳叆", - "output": "杈撳嚭", - "total": "鍚堣", - "percentage": "鍗犳瘮", - "no_data": "鏆傛棤鏁版嵁" + "title": "Token 消费统计", + "hourly": "小时", + "daily": "日", + "weekly": "周", + "total_tokens": "总 Token", + "input_tokens": "输入 Token", + "output_tokens": "输出 Token", + "accounts_used": "活跃账号", + "models_used": "使用模型", + "model_trend": "分模型使用趋势", + "account_trend": "分账号使用趋势", + "usage_trend": "Token 使用趋势", + "by_account": "分账号统计", + "by_model": "按模型", + "by_account_view": "按账号", + "model_details": "分模型详细统计", + "account_details": "账号详细统计", + "model": "模型", + "account": "账号", + "requests": "请求数", + "input": "输入", + "output": "输出", + "total": "合计", + "percentage": "占比", + "no_data": "暂无数据" }, "errors": { "stream": { - "timeout_error": "璇锋眰瓒呮椂,璇锋鏌ョ綉缁滆繛鎺?, - "connection_error": "鏃犳硶杩炴帴鍒版湇鍔″櫒,璇锋鏌ョ綉缁滄垨浠g悊璁剧疆", - "decode_error": "缃戠粶杩炴帴涓嶇ǔ瀹?鏁版嵁浼犺緭涓柇銆傚缓璁? 1) 妫€鏌ョ綉缁滆繛鎺?2) 鏇存崲浠g悊鑺傜偣 3) 绋嶅悗閲嶈瘯", - "stream_error": "鏁版嵁娴佷紶杈撻敊璇?璇风◢鍚庨噸璇?, - "unknown_error": "鍙戠敓鏈煡閿欒,璇风◢鍚庨噸璇? + "timeout_error": "请求超时,请检查网络连接", + "connection_error": "无法连接到服务器,请检查网络或代理设置", + "decode_error": "网络连接不稳定,数据传输中断。建议: 1) 检查网络连接 2) 更换代理节点 3) 稍后重试", + "stream_error": "数据流传输错误,请稍后重试", + "unknown_error": "发生未知错误,请稍后重试" } }, "security": { - "title": "瀹夊叏鐩戞帶", - "refresh_data": "鍒锋柊鏁版嵁", - "refresh": "鍒锋柊", - "tab_logs": "璁块棶鏃ュ織", - "tab_stats": "缁熻鍒嗘瀽", - "tab_blacklist": "榛戝悕鍗曠鐞?, - "tab_whitelist": "鐧藉悕鍗曠鐞?, - "tab_config": "瀹夊叏閰嶇疆", + "title": "安全监控", + "refresh_data": "刷新数据", + "refresh": "刷新", + "tab_logs": "访问日志", + "tab_stats": "统计分析", + "tab_blacklist": "黑名单管理", + "tab_whitelist": "白名单管理", + "tab_config": "安全配置", "stats": { - "total_requests": "鎬昏姹傛暟", - "total_requests_desc": "鎵€鏈夎褰曠殑璇锋眰", - "unique_ips": "鐙珛 IP 鏁?, - "unique_ips_desc": "涓嶅悓鐨勫鎴风 IP 鍦板潃", - "blocked_requests": "鎷︽埅璇锋眰鏁?, - "blocked_requests_desc": "琚鍒欐嫆缁濈殑璇锋眰", - "ip_activity_token_usage": "IP 娲昏穬搴?& Token 娑堣€?, - "hour": "鏃?, - "day": "鏃?, - "week": "鍛?, - "month": "鏈?, - "rank": "鎺掑悕", - "ip_address": "IP 鍦板潃", - "activity_reqs": "娲昏穬搴?(璇锋眰鏁?", - "total_token": "鎬?Token", - "prompt": "鎻愰棶", - "completion": "鍥炵瓟", - "no_data": "鏆傛棤鏁版嵁" + "total_requests": "总请求数", + "total_requests_desc": "所有记录的请求", + "unique_ips": "独立 IP 数", + "unique_ips_desc": "不同的客户端 IP 地址", + "blocked_requests": "拦截请求数", + "blocked_requests_desc": "被规则拒绝的请求", + "ip_activity_token_usage": "IP 活跃度 & Token 消耗", + "hour": "时", + "day": "日", + "week": "周", + "month": "月", + "rank": "排名", + "ip_address": "IP 地址", + "activity_reqs": "活跃度 (请求数)", + "total_token": "总 Token", + "prompt": "提问", + "completion": "回答", + "no_data": "暂无数据" }, "logs": { - "search_placeholder": "鎼滅储 IP, 璺緞, User Agent...", - "username": "鐢ㄦ埛", - "show_blocked_only": "浠呮樉绀鸿鎷︽埅", - "status": "鐘舵€?, - "ip_address": "IP 鍦板潃", - "method": "鏂规硶", - "path": "璺緞", - "duration": "鑰楁椂", - "time": "鏃堕棿", - "reason": "鍘熷洜", - "blocked": "鎷︽埅", - "no_logs": "鏆傛棤鏃ュ織", - "total_records": "鍏?{{total}} 鏉¤褰?, - "prev_page": "涓婁竴椤?, - "next_page": "涓嬩竴椤?, - "page_num": "绗?{{page}} 椤?, - "per_page_suffix": "/椤? + "search_placeholder": "搜索 IP, 路径, User Agent...", + "username": "用户", + "show_blocked_only": "仅显示被拦截", + "status": "状态", + "ip_address": "IP 地址", + "method": "方法", + "path": "路径", + "duration": "耗时", + "time": "时间", + "reason": "原因", + "blocked": "拦截", + "no_logs": "暂无日志", + "total_records": "共 {{total}} 条记录", + "prev_page": "上一页", + "next_page": "下一页", + "page_num": "第 {{page}} 页", + "per_page_suffix": "/页" }, "blacklist": { - "add_ip": "娣诲姞 IP", - "search_placeholder": "鎼滅储...", - "added_at": "娣诲姞鏃堕棿", - "expires_at": "杩囨湡鏃堕棿", - "no_data": "鏆傛棤榛戝悕鍗曟暟鎹?, - "add_title": "娣诲姞鍒伴粦鍚嶅崟", - "ip_cidr_label": "IP 鍦板潃鎴?CIDR", - "ip_cidr_placeholder": "渚嬪 192.168.1.1 鎴?10.0.0.0/24", - "reason_label": "鍘熷洜 (鍙€?", - "reason_placeholder": "渚嬪锛氭伓鎰忔壂鎻?, - "expires_label": "杩囨湡鏃堕棿锛堝皬鏃讹紝鍙€夛級", - "expires_placeholder": "鐣欑┖鍒欐案涔呯敓鏁?, - "cancel": "鍙栨秷", - "confirm": "娣诲姞", - "add_btn": "娣诲姞", - "error_duplicate": "璇?IP 宸插瓨鍦ㄤ簬榛戝悕鍗曚腑", - "error_invalid_ip": "鏃犳晥鐨?IP 鏍煎紡銆傝浣跨敤 IP 鍦板潃鎴?CIDR 琛ㄧず娉曪紙渚嬪 192.168.1.0/24锛?, - "error_add_failed": "娣诲姞澶辫触" + "add_ip": "添加 IP", + "search_placeholder": "搜索...", + "added_at": "添加时间", + "expires_at": "过期时间", + "no_data": "暂无黑名单数据", + "add_title": "添加到黑名单", + "ip_cidr_label": "IP 地址或 CIDR", + "ip_cidr_placeholder": "例如 192.168.1.1 或 10.0.0.0/24", + "reason_label": "原因 (可选)", + "reason_placeholder": "例如:恶意扫描", + "expires_label": "过期时间(小时,可选)", + "expires_placeholder": "留空则永久生效", + "cancel": "取消", + "confirm": "添加", + "add_btn": "添加", + "error_duplicate": "该 IP 已存在于黑名单中", + "error_invalid_ip": "无效的 IP 格式。请使用 IP 地址或 CIDR 表示法(例如 192.168.1.0/24)", + "error_add_failed": "添加失败" }, "whitelist": { - "add_ip": "娣诲姞淇′换 IP", - "no_data": "鏆傛棤鐧藉悕鍗曟暟鎹?, - "add_title": "娣诲姞鍒扮櫧鍚嶅崟", - "description_label": "澶囨敞 (鍙€?", - "description_placeholder": "渚嬪锛氬唴閮ㄦ湇鍔″櫒", - "cancel": "鍙栨秷", - "confirm": "娣诲姞", - "add_btn": "娣诲姞" + "add_ip": "添加信任 IP", + "no_data": "暂无白名单数据", + "add_title": "添加到白名单", + "description_label": "备注 (可选)", + "description_placeholder": "例如:内部服务器", + "cancel": "取消", + "confirm": "添加", + "add_btn": "添加" }, "config": { - "title": "瀹夊叏璁剧疆", - "save": "淇濆瓨鏇存敼", - "saving": "淇濆瓨涓?..", - "blacklist_title": "IP 榛戝悕鍗?, - "blacklist_desc": "绠$悊琚嫤鎴殑 IP 鍦板潃鍜岃鍒欍€?, - "enable_blacklist": "鍚敤榛戝悕鍗曚繚鎶?, - "block_msg_label": "鑷畾涔夋嫤鎴秷鎭?, - "block_msg_desc": "杩斿洖缁欒鎷︽埅瀹㈡埛绔殑鍝嶅簲鍐呭銆?, - "whitelist_title": "IP 鐧藉悕鍗?, - "whitelist_desc": "绠$悊淇′换鐨?IP 鍦板潃銆?, - "enable_whitelist": "鍚敤鐧藉悕鍗曟ā寮?, - "whitelist_warning": "璀﹀憡: 鍚敤鐧藉悕鍗曟ā寮忓皢鎷︽埅鎵€鏈変笉鍦ㄧ櫧鍚嶅崟涓殑 IP 璇锋眰銆傚鏋滄偍閫氳繃浠g悊璁块棶锛岃鍔″繀灏忓績涓嶈灏嗚嚜宸遍攣鍦ㄥ闈€?, - "whitelist_priority": "鐧藉悕鍗曚紭鍏?(瑕嗙洊榛戝悕鍗?", - "whitelist_priority_desc": "鍚敤鍚庯紝鐧藉悕鍗?IP 灏嗚鍏佽璁块棶锛屽嵆浣垮畠浠尮閰嶉粦鍚嶅崟瑙勫垯銆?, - "load_error": "鍔犺浇閰嶇疆澶辫触", - "save_success": "閰嶇疆宸蹭繚瀛?, - "save_error": "淇濆瓨閰嶇疆澶辫触" + "title": "安全设置", + "save": "保存更改", + "saving": "保存中...", + "blacklist_title": "IP 黑名单", + "blacklist_desc": "管理被拦截的 IP 地址和规则。", + "enable_blacklist": "启用黑名单保护", + "block_msg_label": "自定义拦截消息", + "block_msg_desc": "返回给被拦截客户端的响应内容。", + "whitelist_title": "IP 白名单", + "whitelist_desc": "管理信任的 IP 地址。", + "enable_whitelist": "启用白名单模式", + "whitelist_warning": "警告: 启用白名单模式将拦截所有不在白名单中的 IP 请求。如果您通过代理访问,请务必小心不要将自己锁在外面。", + "whitelist_priority": "白名单优先 (覆盖黑名单)", + "whitelist_priority_desc": "启用后,白名单 IP 将被允许访问,即使它们匹配黑名单规则。", + "load_error": "加载配置失败", + "save_success": "配置已保存", + "save_error": "保存配置失败" } }, "user_token": { - "title": "鐢ㄦ埛 Token 绠$悊", - "total_users": "鐢ㄦ埛鎬绘暟", - "active_tokens": "娲昏穬 Token", - "total_created": "绱鍒涘缓", - "create": "鍒涘缓 Token", - "username": "鐢ㄦ埛鍚?, + "title": "用户 Token 管理", + "total_users": "用户总数", + "active_tokens": "活跃 Token", + "total_created": "累计创建", + "create": "创建 Token", + "username": "用户名", "token": "Token", - "expires": "杩囨湡鏃堕棿", - "usage": "浣跨敤閲?, - "ip_limit": "IP 闄愬埗", - "created": "鍒涘缓鏃堕棿", - "today_requests": "浠婃棩璇锋眰鏁?, - "never": "姘镐笉杩囨湡", - "renew": "缁湡", - "renew_button": "缁垂", - "unlimited": "涓嶉檺", - "create_title": "鍒涘缓鏂?Token", - "description": "鎻忚堪", - "curfew": "瀹电鏃堕棿 (鏈嶅姟涓嶅彲鐢ㄦ椂娈?", - "edit_title": "缂栬緫 Token", - "username_required": "鐢ㄦ埛鍚嶄笉鑳戒负绌?, - "renew_success": "缁湡鎴愬姛", - "expires_day": "1 澶?, - "expires_week": "1 鍛?, - "expires_month": "1 涓湀", - "expires_never": "姘镐笉杩囨湡", - "no_data": "鏆傛棤鏁版嵁", - "placeholder_username": "渚嬪: user1", - "placeholder_desc": "閫夊~澶囨敞", - "placeholder_max_ips": "0 = 涓嶉檺鍒?, - "hint_max_ips": "0 琛ㄧず涓嶉檺鍒?, - "hint_curfew": "鐣欑┖鍒欑鐢ㄣ€傚熀浜庢湇鍔″櫒鏃堕棿銆? + "expires": "过期时间", + "usage": "使用量", + "ip_limit": "IP 限制", + "created": "创建时间", + "today_requests": "今日请求数", + "never": "永不过期", + "renew": "续期", + "renew_button": "续费", + "unlimited": "不限", + "create_title": "创建新 Token", + "description": "描述", + "curfew": "宵禁时间 (服务不可用时段)", + "edit_title": "编辑 Token", + "username_required": "用户名不能为空", + "renew_success": "续期成功", + "expires_day": "1 天", + "expires_week": "1 周", + "expires_month": "1 个月", + "expires_never": "永不过期", + "no_data": "暂无数据", + "placeholder_username": "例如: user1", + "placeholder_desc": "选填备注", + "placeholder_max_ips": "0 = 不限制", + "hint_max_ips": "0 表示不限制", + "hint_curfew": "留空则禁用。基于服务器时间。" } -} +} \ No newline at end of file From 7540020e5c86aa0c1ccc5774e433935c1f0073d8 Mon Sep 17 00:00:00 2001 From: Vucius Date: Fri, 12 Jun 2026 23:06:36 +0900 Subject: [PATCH 3/8] fix(rust): remove extra closing braces left behind after refactoring --- src-tauri/src/modules/account.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src-tauri/src/modules/account.rs b/src-tauri/src/modules/account.rs index cdb3bfb82..4acd4ec78 100644 --- a/src-tauri/src/modules/account.rs +++ b/src-tauri/src/modules/account.rs @@ -1846,7 +1846,6 @@ pub async fn fetch_quota_with_retry(account: &mut Account) -> crate::error::AppR q.is_forbidden = true; return Ok(q); } - } } match retry_result { @@ -1870,7 +1869,6 @@ pub async fn fetch_quota_with_retry(account: &mut Account) -> crate::error::AppR } } } - } } // fetch_quota already handles 403, with additional local fallback/validation handling. From cdaa5e729e0102cdea5765ec8bc2b1943a34b758 Mon Sep 17 00:00:00 2001 From: Vucius Date: Fri, 12 Jun 2026 23:22:54 +0900 Subject: [PATCH 4/8] fix_2_shot --- src-tauri/src/modules/tray.rs | 3 ++- src/locales/zh-TW.json | 4 ++-- src/stores/useAccountStore.ts | 10 +++++++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src-tauri/src/modules/tray.rs b/src-tauri/src/modules/tray.rs index a27ddb9a2..5381369ca 100644 --- a/src-tauri/src/modules/tray.rs +++ b/src-tauri/src/modules/tray.rs @@ -15,7 +15,8 @@ pub fn create_tray(app: &tauri::AppHandle) -> tauri::Result<()> { let icon_bytes = include_bytes!("../../icons/tray-icon.png"); let img = image::load_from_memory(icon_bytes) .map_err(|e| { - tauri::Error::Io(std::io::Error::other( + tauri::Error::Io(std::io::Error::new( + std::io::ErrorKind::Other, e.to_string(), )) })? diff --git a/src/locales/zh-TW.json b/src/locales/zh-TW.json index 1a59aa0e2..260a9b14a 100644 --- a/src/locales/zh-TW.json +++ b/src/locales/zh-TW.json @@ -1,4 +1,4 @@ -{ +{ "common": { "empty": "空", "loading": "載入中...", @@ -1048,7 +1048,7 @@ "error_invalid_key": "密碼或 API Key 錯誤,請重試", "error_network": "網路連線失敗,請檢查服務是否正常運行", "note": "注意:如果設置了獨立的管理密碼,請輸入管理密碼;否則請輸入 API_KEY。", - "lookup_hint": "请查看 gui_config.json 或检查环境变量以获取它们。", + "lookup_hint": "請查看 gui_config.json 或檢查環境變數以取得它們。", "config_hint": "或執行 grep -E '\"api_key\"|\"admin_password\"' ~/.antigravity_tools/gui_config.json 查看。" }, "token_stats": { diff --git a/src/stores/useAccountStore.ts b/src/stores/useAccountStore.ts index b9b36ee44..81f6acb12 100644 --- a/src/stores/useAccountStore.ts +++ b/src/stores/useAccountStore.ts @@ -113,9 +113,13 @@ export const useAccountStore = create((set, get) => ({ ]); // Asynchronously refresh quota to update the dashboard, do not block the UI - get().refreshQuota(accountId).catch(e => { - console.error('[Store] Background quota refresh failed after switch:', e); - }); + // NOTE: We call the service directly instead of get().refreshQuota() to avoid + // re-setting loading=true after we just set loading=false. + accountService.fetchAccountQuota(accountId) + .then(() => Promise.all([get().fetchAccounts(), get().fetchCurrentAccount()])) + .catch(e => { + console.error('[Store] Background quota refresh failed after switch:', e); + }); set({ loading: false }); } catch (error) { From 710b4b4bdb46a0f4ac45be1087244f6d6062bf53 Mon Sep 17 00:00:00 2001 From: Vucius Date: Sat, 13 Jun 2026 00:11:29 +0900 Subject: [PATCH 5/8] clean_shot --- src-tauri/src/modules/account.rs | 1 + src-tauri/src/modules/cloudflared.rs | 3 --- src-tauri/src/modules/config.rs | 2 -- src-tauri/src/modules/integration.rs | 4 ++-- src-tauri/src/modules/process.rs | 6 +++--- src-tauri/src/modules/scheduler.rs | 2 ++ src-tauri/src/modules/security_db.rs | 2 ++ src-tauri/src/modules/version.rs | 1 + src-tauri/src/proxy/handlers/claude.rs | 4 ---- src-tauri/src/proxy/handlers/openai.rs | 1 + src-tauri/src/proxy/mappers/claude/request.rs | 1 + src-tauri/src/proxy/token_manager.rs | 8 ++++---- src-tauri/src/proxy/upstream/client.rs | 1 + src-tauri/src/utils/crypto.rs | 1 + src-tauri/src/utils/http.rs | 2 ++ 15 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src-tauri/src/modules/account.rs b/src-tauri/src/modules/account.rs index 4acd4ec78..a592e34fc 100644 --- a/src-tauri/src/modules/account.rs +++ b/src-tauri/src/modules/account.rs @@ -2006,6 +2006,7 @@ pub async fn refresh_all_quotas_logic() -> Result { /// Check and trigger warmup for models that have recovered to 100% /// Called automatically after quota refresh to enable immediate warmup +#[allow(dead_code)] pub async fn check_and_trigger_warmup_for_recovered_models() { let accounts = match list_accounts() { Ok(acc) => acc, diff --git a/src-tauri/src/modules/cloudflared.rs b/src-tauri/src/modules/cloudflared.rs index f3545198f..8c3db5852 100644 --- a/src-tauri/src/modules/cloudflared.rs +++ b/src-tauri/src/modules/cloudflared.rs @@ -7,9 +7,6 @@ use tokio::process::{Child, Command}; use tokio::sync::RwLock; use tracing::{debug, info}; -#[cfg(target_os = "windows")] -use std::os::windows::process::CommandExt; - #[cfg(target_os = "windows")] const CREATE_NO_WINDOW: u32 = 0x08000000; #[cfg(target_os = "windows")] diff --git a/src-tauri/src/modules/config.rs b/src-tauri/src/modules/config.rs index bff151834..7bc48d46c 100644 --- a/src-tauri/src/modules/config.rs +++ b/src-tauri/src/modules/config.rs @@ -3,8 +3,6 @@ use std::fs; use super::account::get_data_dir; use crate::models::AppConfig; -use tracing::warn; - const CONFIG_FILE: &str = "gui_config.json"; /// Load application configuration diff --git a/src-tauri/src/modules/integration.rs b/src-tauri/src/modules/integration.rs index 87e05c240..4320716a2 100644 --- a/src-tauri/src/modules/integration.rs +++ b/src-tauri/src/modules/integration.rs @@ -1,8 +1,6 @@ use crate::models::Account; use crate::modules::{db, device, process, version}; use std::fs; -use std::process::Command; - pub trait SystemIntegration: Send + Sync { /// 当切换账号时执行的系统层操作(如杀进程、写入文件、注入数据库) async fn on_account_switch( @@ -181,6 +179,7 @@ fn write_to_system_keyring(account: &crate::models::Account) -> Result<(), Strin #[cfg(target_os = "macos")] { use base64::{engine::general_purpose::STANDARD, Engine as _}; + use std::process::Command; let encoded_payload = STANDARD.encode(&payload_json); let full_keyring_value = format!("go-keyring-base64:{}", encoded_payload); @@ -299,6 +298,7 @@ fn write_to_system_keyring(account: &crate::models::Account) -> Result<(), Strin { // 2.3 Linux Secret Service API use std::io::Write; + use std::process::Command; let mut child = Command::new("secret-tool") .args([ "store", diff --git a/src-tauri/src/modules/process.rs b/src-tauri/src/modules/process.rs index 572f60c2c..caa2b0860 100644 --- a/src-tauri/src/modules/process.rs +++ b/src-tauri/src/modules/process.rs @@ -457,7 +457,7 @@ fn get_antigravity_pids(target_ide: Option<&str>) -> Vec { } /// Close Antigravity processes -pub fn close_antigravity(timeout_secs: u64, target_ide: Option<&str>) -> Result<(), String> { +pub fn close_antigravity(_timeout_secs: u64, target_ide: Option<&str>) -> Result<(), String> { crate::modules::logger::log_info(&format!("Closing Antigravity ({:?})...", target_ide)); #[cfg(target_os = "windows")] @@ -597,7 +597,7 @@ pub fn close_antigravity(timeout_secs: u64, target_ide: Option<&str>) -> Result< } // Wait for graceful exit (max 70% of timeout_secs) - let graceful_timeout = (timeout_secs * 7) / 10; + let graceful_timeout = (_timeout_secs * 7) / 10; let start = std::time::Instant::now(); while start.elapsed() < Duration::from_secs(graceful_timeout) { if !is_antigravity_running(target_ide) { @@ -705,7 +705,7 @@ pub fn close_antigravity(timeout_secs: u64, target_ide: Option<&str>) -> Result< } // Wait for graceful exit - let graceful_timeout = (timeout_secs * 7) / 10; + let graceful_timeout = (_timeout_secs * 7) / 10; let start = std::time::Instant::now(); while start.elapsed() < Duration::from_secs(graceful_timeout) { if !is_antigravity_running(target_ide) { diff --git a/src-tauri/src/modules/scheduler.rs b/src-tauri/src/modules/scheduler.rs index 3935498e2..f19be4fdb 100644 --- a/src-tauri/src/modules/scheduler.rs +++ b/src-tauri/src/modules/scheduler.rs @@ -50,6 +50,7 @@ pub fn check_cooldown(key: &str, cooldown_seconds: i64) -> bool { } } +#[allow(dead_code)] pub fn start_scheduler( app_handle: Option, proxy_state: crate::commands::proxy::ProxyServiceState, @@ -306,6 +307,7 @@ pub fn start_scheduler( } /// Trigger immediate smart warmup check for a single account +#[allow(dead_code)] pub async fn trigger_warmup_for_account(account: &Account) { // Get valid token let Ok((token, pid)) = quota::get_valid_token_for_warmup(account).await else { diff --git a/src-tauri/src/modules/security_db.rs b/src-tauri/src/modules/security_db.rs index 6f2fa4c85..96a6804ca 100644 --- a/src-tauri/src/modules/security_db.rs +++ b/src-tauri/src/modules/security_db.rs @@ -359,6 +359,7 @@ pub fn get_top_ips(limit: usize, hours: i64) -> Result, String> { } /// 清理旧的 IP 访问日志 +#[allow(dead_code)] pub fn cleanup_old_ip_logs(days: i64) -> Result { let conn = connect_db()?; @@ -655,6 +656,7 @@ pub fn clear_ip_access_logs() -> Result<(), String> { } /// 获取 IP 访问日志总数 +#[allow(dead_code)] pub fn get_ip_access_logs_count( ip_filter: Option<&str>, blocked_only: bool, diff --git a/src-tauri/src/modules/version.rs b/src-tauri/src/modules/version.rs index 9c1cc21fe..15ae931f3 100644 --- a/src-tauri/src/modules/version.rs +++ b/src-tauri/src/modules/version.rs @@ -12,6 +12,7 @@ pub struct AntigravityVersion { } /// 从任意字符串中提取第一个语义化版本号 (X.Y.Z) +#[allow(dead_code)] fn extract_semver(raw: &str) -> Option { for token in raw.split(|c: char| c.is_whitespace() || c == ',' || c == ';') { let t = token.trim_matches(|c: char| c == '"' || c == '\'' || c == '(' || c == ')'); diff --git a/src-tauri/src/proxy/handlers/claude.rs b/src-tauri/src/proxy/handlers/claude.rs index 4e91f9674..dba459ea6 100644 --- a/src-tauri/src/proxy/handlers/claude.rs +++ b/src-tauri/src/proxy/handlers/claude.rs @@ -1562,7 +1562,6 @@ pub async fn handle_messages( determine_retry_strategy(status_code, &error_text, retried_without_thinking); // 执行退避 - let mut force_rotate = false; if apply_retry_strategy( retry_strategy.clone(), attempt, @@ -1578,9 +1577,6 @@ pub async fn handle_messages( "[{}] Keeping same account for status {} (Grace Retry or Server Issue)", trace_id, status_code ); - force_rotate = false; - } else { - force_rotate = true; } continue; } else { diff --git a/src-tauri/src/proxy/handlers/openai.rs b/src-tauri/src/proxy/handlers/openai.rs index c3ebd1d22..8c3ad34eb 100644 --- a/src-tauri/src/proxy/handlers/openai.rs +++ b/src-tauri/src/proxy/handlers/openai.rs @@ -1674,6 +1674,7 @@ pub async fn handle_list_models(State(state): State) -> impl IntoRespo /// OpenAI Images API: POST /v1/images/generations /// 处理图像生成请求,转换为 Gemini API 格式 +#[allow(dead_code)] pub async fn handle_chat_redirection( State(state): State, headers: HeaderMap, diff --git a/src-tauri/src/proxy/mappers/claude/request.rs b/src-tauri/src/proxy/mappers/claude/request.rs index 57d99f2a6..e29b19f49 100644 --- a/src-tauri/src/proxy/mappers/claude/request.rs +++ b/src-tauri/src/proxy/mappers/claude/request.rs @@ -430,6 +430,7 @@ pub fn transform_claude_request_in( // Map model name (Use standard mapping) // [IMPROVED] 提取 web search 模型为常量,便于维护 + #[allow(dead_code)] const WEB_SEARCH_FALLBACK_MODEL: &str = "gemini-2.5-flash"; let mapped_model = diff --git a/src-tauri/src/proxy/token_manager.rs b/src-tauri/src/proxy/token_manager.rs index 39d56232b..6ac004cae 100644 --- a/src-tauri/src/proxy/token_manager.rs +++ b/src-tauri/src/proxy/token_manager.rs @@ -1871,13 +1871,13 @@ impl TokenManager { } else { // [NEW] 针对 fetch_project_id 实现基于 SingleFlight 的异步合并 // 1. 检查是否已有 inflight 请求 - let (mut rx, is_new) = { + let (_rx, is_new) = { if let Some(existing_rx) = self.load_code_assist_inflight.get(&token.account_id) { (existing_rx.value().clone(), false) } else { // 创建新的 inflight 频道 - let (tx, rx) = tokio::sync::watch::channel(None); + let (_tx, rx) = tokio::sync::watch::channel(None); self.load_code_assist_inflight .insert(token.account_id.clone(), rx.clone()); (rx, true) @@ -1888,7 +1888,7 @@ impl TokenManager { // 仅由“第一个发现者”执行真实请求 tracing::debug!("账号 {} 启动 [SingleFlight] ProjectID 探测...", token.email); - let result = + let _result = match crate::proxy::project_resolver::fetch_project_id(&token.access_token) .await { @@ -1903,7 +1903,7 @@ impl TokenManager { }; // 广播结果并清理 inflight - if let Some(mut entry) = + if let Some(_entry) = self.load_code_assist_inflight.get_mut(&token.account_id) { // 这里虽然是 rx,但在 Rust 中 watch 不需要 tx 也可以通过私有方式操作? diff --git a/src-tauri/src/proxy/upstream/client.rs b/src-tauri/src/proxy/upstream/client.rs index 9301dec7f..b096142c2 100644 --- a/src-tauri/src/proxy/upstream/client.rs +++ b/src-tauri/src/proxy/upstream/client.rs @@ -44,6 +44,7 @@ pub fn mask_email(email: &str) -> String { } /// [NEW] 错误日志脱敏:抹除报错信息中的 access_token, proxy_url 等敏感凭证 +#[allow(dead_code)] pub fn sanitize_error_for_log(error_text: &str) -> String { // 抹除常见敏感 key 的值 let re = regex::Regex::new(r#"(?i)(access_token|refresh_token|id_token|authorization|api_key|secret|password|proxy_url|http_proxy|https_proxy)\s*[:=]\s*[^"'\\\s,}\]]+"#).unwrap(); diff --git a/src-tauri/src/utils/crypto.rs b/src-tauri/src/utils/crypto.rs index 4c6823ac5..d976a552f 100644 --- a/src-tauri/src/utils/crypto.rs +++ b/src-tauri/src/utils/crypto.rs @@ -119,6 +119,7 @@ fn decrypt_string_v2(encrypted: &str) -> Result { String::from_utf8(plaintext).map_err(|e| format!("UTF-8 conversion failed: {}", e)) } +#[allow(dead_code)] pub fn decrypt_string(encrypted: &str) -> Result { if encrypted.starts_with(ENCRYPTED_V2_PREFIX) { decrypt_string_v2(&encrypted[ENCRYPTED_V2_PREFIX.len()..]) diff --git a/src-tauri/src/utils/http.rs b/src-tauri/src/utils/http.rs index 8af711e47..14f62b642 100644 --- a/src-tauri/src/utils/http.rs +++ b/src-tauri/src/utils/http.rs @@ -8,6 +8,7 @@ use rquest_util::Emulation; pub static SHARED_CLIENT: Lazy = Lazy::new(|| create_base_client(15)); /// Global shared HTTP client (Long timeout: 60s, for warmup etc.) +#[allow(dead_code)] pub static SHARED_CLIENT_LONG: Lazy = Lazy::new(|| create_base_client(60)); /// Global shared standard HTTP client (15s timeout, NO JA3 Emulation) @@ -50,6 +51,7 @@ pub fn get_client() -> Client { } /// Get long timeout HTTP client (60s timeout) +#[allow(dead_code)] pub fn get_long_client() -> Client { SHARED_CLIENT_LONG.clone() } From d9ec105492c514b90e9d90779d4b69d2db197dca Mon Sep 17 00:00:00 2001 From: Vucius Date: Sat, 13 Jun 2026 01:24:46 +0900 Subject: [PATCH 6/8] clean_1_shot --- src-tauri/src/modules/user_token_db.rs | 2 +- src-tauri/src/proxy/upstream/retry.rs | 2 +- vite.config.ts | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src-tauri/src/modules/user_token_db.rs b/src-tauri/src/modules/user_token_db.rs index 90b59531c..de583e2ec 100644 --- a/src-tauri/src/modules/user_token_db.rs +++ b/src-tauri/src/modules/user_token_db.rs @@ -4,7 +4,7 @@ #![allow(dead_code)] // 用户令牌存储,部分接口留作后续扩展 -use chrono::{FixedOffset, Local, Timelike, Utc}; +use chrono::{FixedOffset, Timelike, Utc}; use rusqlite::{params, Connection, OptionalExtension}; use serde::{Deserialize, Serialize}; use std::path::PathBuf; diff --git a/src-tauri/src/proxy/upstream/retry.rs b/src-tauri/src/proxy/upstream/retry.rs index 03589250d..03438fd5f 100644 --- a/src-tauri/src/proxy/upstream/retry.rs +++ b/src-tauri/src/proxy/upstream/retry.rs @@ -58,7 +58,7 @@ pub fn parse_duration_ms(duration_str: &str) -> Option { /// 从 429 错误中提取 retry delay (深度递归解析) pub fn parse_retry_delay(error_text: &str) -> Option { - use serde_json::Value; + // Removed unused import: use serde_json::Value; // 1. 尝试正则提取 (针对非 JSON 文本或嵌套不深的文本) for re in RE_QUOTA_PATTERNS.iter() { diff --git a/vite.config.ts b/vite.config.ts index c8793496b..992f561ba 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -7,6 +7,9 @@ const host = process.env.TAURI_DEV_HOST; // https://vite.dev/config/ export default defineConfig(async () => ({ plugins: [react()], + build: { + chunkSizeWarningLimit: 1500, + }, // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build` // From 4cced5cfa38c47b39ae0104b25552db2cfc0f590 Mon Sep 17 00:00:00 2001 From: Vucius Date: Sat, 13 Jun 2026 01:54:18 +0900 Subject: [PATCH 7/8] clean_2_shot --- src-tauri/src/proxy/cli_sync.rs | 1 + src-tauri/src/proxy/handlers/gemini.rs | 4 ---- src-tauri/src/proxy/handlers/openai.rs | 4 ---- src-tauri/src/proxy/mappers/common_utils.rs | 2 +- src-tauri/src/proxy/mappers/gemini/wrapper.rs | 4 ++-- src-tauri/src/proxy/token_manager.rs | 2 +- src-tauri/src/utils/command.rs | 2 ++ 7 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src-tauri/src/proxy/cli_sync.rs b/src-tauri/src/proxy/cli_sync.rs index e3f0e267b..edfb7e887 100644 --- a/src-tauri/src/proxy/cli_sync.rs +++ b/src-tauri/src/proxy/cli_sync.rs @@ -162,6 +162,7 @@ fn run_version_command(executable_path: &PathBuf) -> Option { } /// 提取版本号(使用更精确的 semver 匹配) +#[cfg(target_os = "windows")] fn extract_version(s: &str) -> Option { // 匹配 semver 格式: x.y.z 或 x.y let re = regex::Regex::new(r"(\d+\.\d+(?:\.\d+)?)").ok()?; diff --git a/src-tauri/src/proxy/handlers/gemini.rs b/src-tauri/src/proxy/handlers/gemini.rs index b1241096f..00ca2f646 100644 --- a/src-tauri/src/proxy/handlers/gemini.rs +++ b/src-tauri/src/proxy/handlers/gemini.rs @@ -629,15 +629,11 @@ pub async fn handle_generate( // 判断是否需要轮换账号 // 判断是否需要轮换账号 - let mut force_rotate = false; if !should_rotate_account(status_code, Some(&strategy)) { debug!( "[{}] Keeping same account for status {} (Gemini server-side issue or Grace Retry)", trace_id, status_code ); - force_rotate = false; - } else { - force_rotate = true; } } diff --git a/src-tauri/src/proxy/handlers/openai.rs b/src-tauri/src/proxy/handlers/openai.rs index 8c3ad34eb..578f94977 100644 --- a/src-tauri/src/proxy/handlers/openai.rs +++ b/src-tauri/src/proxy/handlers/openai.rs @@ -632,15 +632,11 @@ pub async fn handle_chat_completions( // 判断是否需要轮换账号 // 判断是否需要轮换账号 - let mut force_rotate = false; if !should_rotate_account(status_code, Some(&strategy)) { debug!( "[{}] Keeping same account for status {} (Grace Retry or Server Issue)", trace_id, status_code ); - force_rotate = false; - } else { - force_rotate = true; } // 2. [REMOVED] 不再特殊处理 QUOTA_EXHAUSTED,允许账号轮换 diff --git a/src-tauri/src/proxy/mappers/common_utils.rs b/src-tauri/src/proxy/mappers/common_utils.rs index 904b635f1..4dbc383ea 100644 --- a/src-tauri/src/proxy/mappers/common_utils.rs +++ b/src-tauri/src/proxy/mappers/common_utils.rs @@ -355,7 +355,7 @@ fn calculate_aspect_ratio_from_size(size: &str) -> &'static str { } /// Inject current googleSearch tool and ensure no duplicate legacy search tools -pub fn inject_google_search_tool(body: &mut Value, mapped_model: Option<&str>) { +pub fn inject_google_search_tool(body: &mut Value, _mapped_model: Option<&str>) { if let Some(obj) = body.as_object_mut() { let tools_entry = obj.entry("tools").or_insert_with(|| json!([])); if let Some(tools_arr) = tools_entry.as_array_mut() { diff --git a/src-tauri/src/proxy/mappers/gemini/wrapper.rs b/src-tauri/src/proxy/mappers/gemini/wrapper.rs index 57422283b..21e397874 100644 --- a/src-tauri/src/proxy/mappers/gemini/wrapper.rs +++ b/src-tauri/src/proxy/mappers/gemini/wrapper.rs @@ -24,7 +24,7 @@ pub fn wrap_request( }; // [ADDED v4.1.24] 计算 message_count 供 requestId 使用 - let message_count = body + let _message_count = body .get("contents") .and_then(|c| c.as_array()) .map(|a| a.len()) @@ -571,7 +571,7 @@ pub fn wrap_request( )); } - let sid = session_id.unwrap_or("default"); + let _sid = session_id.unwrap_or("default"); // [NEW] 1. 深度对齐 requestId 格式 (官方格式: agent/{timestamp_ms}/{random_hex_8bytes}) // 每次请求生成完全唯一的 ID,避免重试时的幂等性冲突导致 Google 返回旧缓存 diff --git a/src-tauri/src/proxy/token_manager.rs b/src-tauri/src/proxy/token_manager.rs index 6ac004cae..a08b1cdaf 100644 --- a/src-tauri/src/proxy/token_manager.rs +++ b/src-tauri/src/proxy/token_manager.rs @@ -1835,7 +1835,7 @@ impl TokenManager { e ); if e.contains("\"invalid_grant\"") || e.contains("invalid_grant") { - self.disable_account( + let _ = self.disable_account( &token.account_id, &format!("invalid_grant: {}", e), ) diff --git a/src-tauri/src/utils/command.rs b/src-tauri/src/utils/command.rs index 4f6b43e09..bd9bf2d88 100644 --- a/src-tauri/src/utils/command.rs +++ b/src-tauri/src/utils/command.rs @@ -1,3 +1,5 @@ +#![cfg(target_os = "windows")] + use std::process::Command as StdCommand; use tokio::process::Command as TokioCommand; From 5e52ca93338167fdea94dd98a584333188a5fc67 Mon Sep 17 00:00:00 2001 From: Vucius Date: Sat, 13 Jun 2026 02:45:40 +0900 Subject: [PATCH 8/8] style: run cargo fmt to fix formatting checks --- src-tauri/src/commands/proxy.rs | 3 +- src-tauri/src/modules/account.rs | 200 +++++++++++++-------------- src-tauri/src/modules/integration.rs | 2 +- src-tauri/src/proxy/token_manager.rs | 14 +- 4 files changed, 108 insertions(+), 111 deletions(-) diff --git a/src-tauri/src/commands/proxy.rs b/src-tauri/src/commands/proxy.rs index fa1d3e2ee..d6d9fc554 100644 --- a/src-tauri/src/commands/proxy.rs +++ b/src-tauri/src/commands/proxy.rs @@ -439,7 +439,8 @@ pub async fn export_proxy_logs_json(file_path: String, json_data: String) -> Res let pretty_json = serde_json::to_string_pretty(&logs).map_err(|e| format!("Failed to serialize: {}", e))?; - std::fs::write(&validated_path, pretty_json).map_err(|e| format!("Failed to write file: {}", e))?; + std::fs::write(&validated_path, pretty_json) + .map_err(|e| format!("Failed to write file: {}", e))?; Ok(count) } diff --git a/src-tauri/src/modules/account.rs b/src-tauri/src/modules/account.rs index a592e34fc..82bd89364 100644 --- a/src-tauri/src/modules/account.rs +++ b/src-tauri/src/modules/account.rs @@ -1750,125 +1750,121 @@ pub async fn fetch_quota_with_retry(account: &mut Account) -> crate::error::AppR // 3. Handle 401 error if let Err(AppError::Network(_, Some(code))) = result { - if code == 401 { - modules::logger::log_warn(&format!( - "401 Unauthorized for {}, forcing refresh...", - account.email - )); + if code == 401 { + modules::logger::log_warn(&format!( + "401 Unauthorized for {}, forcing refresh...", + account.email + )); - // Force refresh - let token_res = match oauth::refresh_access_token_with_client( - &account.token.refresh_token, - Some(&account.id), - account.token.oauth_client_key.as_deref(), - ) - .await - { - Ok(t) => t, - Err(e) => { - if e.contains("invalid_grant") { - modules::logger::log_error(&format!( + // Force refresh + let token_res = match oauth::refresh_access_token_with_client( + &account.token.refresh_token, + Some(&account.id), + account.token.oauth_client_key.as_deref(), + ) + .await + { + Ok(t) => t, + Err(e) => { + if e.contains("invalid_grant") { + modules::logger::log_error(&format!( "Disabling account {} due to invalid_grant during forced refresh (quota check)", account.email )); - account.disabled = true; - account.disabled_at = Some(chrono::Utc::now().timestamp()); - account.disabled_reason = Some(format!("invalid_grant: {}", e)); - let _ = save_account(account); - crate::proxy::server::trigger_account_reload(&account.id); - } - return Err(AppError::OAuth(e)); + account.disabled = true; + account.disabled_at = Some(chrono::Utc::now().timestamp()); + account.disabled_reason = Some(format!("invalid_grant: {}", e)); + let _ = save_account(account); + crate::proxy::server::trigger_account_reload(&account.id); } - }; - - let new_token = TokenData::new( - token_res.access_token.clone(), - account.token.refresh_token.clone(), - token_res.expires_in, - account.token.email.clone(), - account.token.project_id.clone(), // Keep original project_id - None, // Add None as session_id - account.token.is_gcp_tos, - token_res.id_token.clone(), - ) - .with_oauth_client_key( - token_res - .oauth_client_key - .clone() - .or_else(|| account.token.oauth_client_key.clone()), - ); + return Err(AppError::OAuth(e)); + } + }; + + let new_token = TokenData::new( + token_res.access_token.clone(), + account.token.refresh_token.clone(), + token_res.expires_in, + account.token.email.clone(), + account.token.project_id.clone(), // Keep original project_id + None, // Add None as session_id + account.token.is_gcp_tos, + token_res.id_token.clone(), + ) + .with_oauth_client_key( + token_res + .oauth_client_key + .clone() + .or_else(|| account.token.oauth_client_key.clone()), + ); - // Re-fetch display name - let name = if account.name.is_none() - || account.name.as_ref().map_or(false, |n| n.trim().is_empty()) - { - match oauth::get_user_info(&token_res.access_token, Some(&account.id)).await { - Ok(user_info) => user_info.get_display_name(), - Err(_) => None, - } - } else { - account.name.clone() - }; + // Re-fetch display name + let name = if account.name.is_none() + || account.name.as_ref().map_or(false, |n| n.trim().is_empty()) + { + match oauth::get_user_info(&token_res.access_token, Some(&account.id)).await { + Ok(user_info) => user_info.get_display_name(), + Err(_) => None, + } + } else { + account.name.clone() + }; - account.token = new_token.clone(); - account.name = name.clone(); - upsert_account(account.email.clone(), name, new_token.clone()) - .map_err(AppError::Account)?; - - // Retry query - let retry_result: crate::error::AppResult<(QuotaData, Option)> = - modules::fetch_quota( - &new_token.access_token, - &account.email, - Some(&account.id), - ) + account.token = new_token.clone(); + account.name = name.clone(); + upsert_account(account.email.clone(), name, new_token.clone()) + .map_err(AppError::Account)?; + + // Retry query + let retry_result: crate::error::AppResult<(QuotaData, Option)> = + modules::fetch_quota(&new_token.access_token, &account.email, Some(&account.id)) .await; - // Also handle project_id saving during retry - if let Ok((ref _q, ref project_id)) = retry_result { - if project_id.is_some() && *project_id != account.token.project_id { - modules::logger::log_info(&format!( - "Detected update of project_id after retry ({}), saving...", - account.email - )); - account.token.project_id = project_id.clone(); - let _ = upsert_account( - account.email.clone(), - account.name.clone(), - account.token.clone(), - ); - } + // Also handle project_id saving during retry + if let Ok((ref _q, ref project_id)) = retry_result { + if project_id.is_some() && *project_id != account.token.project_id { + modules::logger::log_info(&format!( + "Detected update of project_id after retry ({}), saving...", + account.email + )); + account.token.project_id = project_id.clone(); + let _ = upsert_account( + account.email.clone(), + account.name.clone(), + account.token.clone(), + ); } + } - if let Err(AppError::Network(_, Some(code))) = retry_result { - if code == 403 { - let mut q = QuotaData::new(); - q.is_forbidden = true; - return Ok(q); - } + if let Err(AppError::Network(_, Some(code))) = retry_result { + if code == 403 { + let mut q = QuotaData::new(); + q.is_forbidden = true; + return Ok(q); } + } - match retry_result { - Ok((q, _)) => { - clear_validation_blocked(account); - return Ok(q); + match retry_result { + Ok((q, _)) => { + clear_validation_blocked(account); + return Ok(q); + } + Err(e) => { + if is_validation_required_error(&e) { + mark_validation_blocked(account, &e.to_string()); } - Err(e) => { - if is_validation_required_error(&e) { - mark_validation_blocked(account, &e.to_string()); - } - if let Some(cached) = recover_cached_quota_on_rate_limit(account, &e) { - mark_validation_blocked(account, &format_rate_limit_block_reason(&e)); - modules::logger::log_warn(&format!( - "Quota API rate-limited for {}, using cached model list as fallback", - account.email - )); - return Ok(cached); - } - return Err(e); + if let Some(cached) = recover_cached_quota_on_rate_limit(account, &e) { + mark_validation_blocked(account, &format_rate_limit_block_reason(&e)); + modules::logger::log_warn(&format!( + "Quota API rate-limited for {}, using cached model list as fallback", + account.email + )); + return Ok(cached); } + return Err(e); } } + } } // fetch_quota already handles 403, with additional local fallback/validation handling. diff --git a/src-tauri/src/modules/integration.rs b/src-tauri/src/modules/integration.rs index 4320716a2..af794365d 100644 --- a/src-tauri/src/modules/integration.rs +++ b/src-tauri/src/modules/integration.rs @@ -179,7 +179,7 @@ fn write_to_system_keyring(account: &crate::models::Account) -> Result<(), Strin #[cfg(target_os = "macos")] { use base64::{engine::general_purpose::STANDARD, Engine as _}; - use std::process::Command; + use std::process::Command; let encoded_payload = STANDARD.encode(&payload_json); let full_keyring_value = format!("go-keyring-base64:{}", encoded_payload); diff --git a/src-tauri/src/proxy/token_manager.rs b/src-tauri/src/proxy/token_manager.rs index a08b1cdaf..6137441d4 100644 --- a/src-tauri/src/proxy/token_manager.rs +++ b/src-tauri/src/proxy/token_manager.rs @@ -1835,11 +1835,12 @@ impl TokenManager { e ); if e.contains("\"invalid_grant\"") || e.contains("invalid_grant") { - let _ = self.disable_account( - &token.account_id, - &format!("invalid_grant: {}", e), - ) - .await; + let _ = self + .disable_account( + &token.account_id, + &format!("invalid_grant: {}", e), + ) + .await; } last_error = Some(format!("Token refresh failed: {}", e)); attempted.insert(token.account_id.clone()); @@ -1903,8 +1904,7 @@ impl TokenManager { }; // 广播结果并清理 inflight - if let Some(_entry) = - self.load_code_assist_inflight.get_mut(&token.account_id) + if let Some(_entry) = self.load_code_assist_inflight.get_mut(&token.account_id) { // 这里虽然是 rx,但在 Rust 中 watch 不需要 tx 也可以通过私有方式操作? // 修正:我们需要持有 tx。重新设计此处:使用 Mutex 或在 scope 外持有 tx。