diff --git a/ui/desktop/package.json b/ui/desktop/package.json index 86d0481b9..e36cee0df 100644 --- a/ui/desktop/package.json +++ b/ui/desktop/package.json @@ -42,9 +42,10 @@ "test:integration:watch": "vitest --config vitest.integration.config.ts", "test:integration:debug": "DEBUG=1 vitest run --config vitest.integration.config.ts", "i18n:extract": "formatjs extract 'src/**/*.{ts,tsx}' --ignore '**/*.d.ts' --out-file src/i18n/messages/en.json --flatten && pnpm run i18n:compile", - "i18n:check": "node scripts/i18n-check.js", + "i18n:check": "node scripts/i18n-check.js && node scripts/i18n-validate-locale.js", "i18n:compile": "node scripts/i18n-compile.js", - "i18n:validate-ja": "node scripts/i18n-validate-locale.js ja" + "i18n:validate-ja": "node scripts/i18n-validate-locale.js ja", + "i18n:validate-locale": "node scripts/i18n-validate-locale.js" }, "dependencies": { "@aaif/goose-sdk": "workspace:*", @@ -118,6 +119,7 @@ "@electron/fuses": "^1.8.0", "@eslint/js": "^9.39.2", "@formatjs/cli": "^6.14.0", + "@formatjs/icu-messageformat-parser": "3.5.3", "@hey-api/openapi-ts": "^0.93.0", "@modelcontextprotocol/sdk": "^1.27.0", "@playwright/test": "^1.58.2", diff --git a/ui/desktop/scripts/i18n-validate-locale.js b/ui/desktop/scripts/i18n-validate-locale.js index 69990febd..157512f06 100644 --- a/ui/desktop/scripts/i18n-validate-locale.js +++ b/ui/desktop/scripts/i18n-validate-locale.js @@ -1,56 +1,146 @@ #!/usr/bin/env node /** - * Validate that a translated locale catalog mirrors en.json and preserves ICU placeholders. + * Validate that translated locale catalogs mirror en.json and preserve ICU placeholders. + * Pass one or more locale codes to validate specific catalogs, or no arguments to validate all locales. */ const fs = require('fs'); const path = require('path'); +const { TYPE, parse } = require('@formatjs/icu-messageformat-parser'); + +const requestedLocales = process.argv.slice(2); + +if (requestedLocales.includes('en')) { + console.error('en is the source catalog and cannot be validated as a translated locale.'); + process.exit(1); +} -const locale = process.argv[2] || 'ja'; const projectDir = path.join(__dirname, '..'); const messagesDir = path.join(projectDir, 'src', 'i18n', 'messages'); const enPath = path.join(messagesDir, 'en.json'); -const localePath = path.join(messagesDir, locale + '.json'); function readJson(file) { return JSON.parse(fs.readFileSync(file, 'utf8')); } -function extractPlaceholders(message) { - const placeholders = new Set(); - const re = /\{\s*([A-Za-z_][A-Za-z0-9_]*)\s*(?=[},])/g; - let match; - while ((match = re.exec(message)) !== null) { - placeholders.add(match[1]); +function collectArguments(elements, args) { + for (const element of elements) { + switch (element.type) { + case TYPE.argument: + case TYPE.number: + case TYPE.date: + case TYPE.time: + args.add(element.value); + break; + case TYPE.select: + case TYPE.plural: + args.add(element.value); + for (const option of Object.values(element.options)) { + collectArguments(option.value, args); + } + break; + case TYPE.tag: + args.add(element.value); + collectArguments(element.children, args); + break; + } + } +} + +function extractPlaceholders(message) { + const args = new Set(); + collectArguments(parse(message), args); + return [...args].sort(); +} + +function listLocales() { + return fs + .readdirSync(messagesDir) + .filter((file) => file.endsWith('.json') && file !== 'en.json') + .map((file) => path.basename(file, '.json')) + .sort(); +} + +function validateLocale(locale, en, enKeys) { + const localePath = path.join(messagesDir, locale + '.json'); + + if (!fs.existsSync(localePath)) { + return { + locale, + missingFile: true, + missing: [], + extra: [], + placeholderIssues: [], + }; + } + + const translated = readJson(localePath); + const localeKeys = Object.keys(translated).sort(); + const missing = enKeys.filter((key) => !Object.prototype.hasOwnProperty.call(translated, key)); + const extra = localeKeys.filter((key) => !Object.prototype.hasOwnProperty.call(en, key)); + const placeholderIssues = []; + + for (const key of enKeys) { + if (!translated[key]) continue; + const source = en[key].defaultMessage || ''; + const target = translated[key].defaultMessage || ''; + const sourcePlaceholders = extractPlaceholders(source); + const targetPlaceholders = extractPlaceholders(target); + if (JSON.stringify(sourcePlaceholders) !== JSON.stringify(targetPlaceholders)) { + placeholderIssues.push({ key, sourcePlaceholders, targetPlaceholders }); + } + } + + return { locale, missingFile: false, missing, extra, placeholderIssues }; +} + +function printIssues(result) { + const { locale, missingFile, missing, extra, placeholderIssues } = result; + if (missingFile) { + console.error('Missing locale file for ' + locale + '.'); + } + if (missing.length) { + console.error( + 'Missing ' + locale + ' keys (' + missing.length + ', showing first 50):', + missing.slice(0, 50) + ); + } + if (extra.length) { + console.error( + 'Extra ' + locale + ' keys (' + extra.length + ', showing first 50):', + extra.slice(0, 50) + ); + } + if (placeholderIssues.length) { + console.error( + 'Placeholder issues in ' + locale + ' (' + placeholderIssues.length + ', showing first 20):', + placeholderIssues.slice(0, 20) + ); } - return [...placeholders].sort(); } const en = readJson(enPath); -const translated = readJson(localePath); const enKeys = Object.keys(en).sort(); -const localeKeys = Object.keys(translated).sort(); +const locales = requestedLocales.length ? requestedLocales : listLocales(); -const missing = enKeys.filter((key) => !Object.prototype.hasOwnProperty.call(translated, key)); -const extra = localeKeys.filter((key) => !Object.prototype.hasOwnProperty.call(en, key)); -const placeholderIssues = []; - -for (const key of enKeys) { - if (!translated[key]) continue; - const source = en[key].defaultMessage || ''; - const target = translated[key].defaultMessage || ''; - const sourcePlaceholders = extractPlaceholders(source); - const targetPlaceholders = extractPlaceholders(target); - if (JSON.stringify(sourcePlaceholders) !== JSON.stringify(targetPlaceholders)) { - placeholderIssues.push({ key, sourcePlaceholders, targetPlaceholders }); - } -} - -if (missing.length || extra.length || placeholderIssues.length) { - if (missing.length) console.error('Missing ' + locale + ' keys:', missing.slice(0, 50)); - if (extra.length) console.error('Extra ' + locale + ' keys:', extra.slice(0, 50)); - if (placeholderIssues.length) console.error('Placeholder issues:', placeholderIssues.slice(0, 20)); +if (!locales.length) { + console.error('No translated locale catalogs found.'); process.exit(1); } -console.log('i18n locale "' + locale + '" is valid (' + enKeys.length + ' messages).'); +const results = locales.map((locale) => validateLocale(locale, en, enKeys)); +const failures = results.filter( + ({ missingFile, missing, extra, placeholderIssues }) => + missingFile || missing.length || extra.length || placeholderIssues.length +); +for (const result of failures) { + printIssues(result); +} + +if (failures.length) { + process.exit(1); +} + +console.log( + 'i18n locale validation passed for ' + locales.join(', ') + ' (' + enKeys.length + ' messages).' +); diff --git a/ui/desktop/src/i18n/messages/ru.json b/ui/desktop/src/i18n/messages/ru.json index 808b499c5..2ebb91da7 100644 --- a/ui/desktop/src/i18n/messages/ru.json +++ b/ui/desktop/src/i18n/messages/ru.json @@ -44,6 +44,66 @@ "appsView.title": { "defaultMessage": "Приложения" }, + "authSettings.activeProviderWarning": { + "defaultMessage": "Это активный провайдер. Новые запросы могут завершаться ошибкой, пока вы не настроите другие учетные данные." + }, + "authSettings.cancel": { + "defaultMessage": "Отмена" + }, + "authSettings.delete": { + "defaultMessage": "Удалить" + }, + "authSettings.deleteCredential": { + "defaultMessage": "Удалить учетные данные" + }, + "authSettings.deleteMessage": { + "defaultMessage": "Удалить учетные данные {name} для {provider}?" + }, + "authSettings.deleteTitle": { + "defaultMessage": "Удалить учетные данные" + }, + "authSettings.deleted": { + "defaultMessage": "Учетные данные удалены" + }, + "authSettings.description": { + "defaultMessage": "Управляйте учетными данными провайдеров, сохраненными локально в goose." + }, + "authSettings.empty": { + "defaultMessage": "Локально сохраненные учетные данные провайдеров не найдены." + }, + "authSettings.expiresAt": { + "defaultMessage": "Истекает {date}" + }, + "authSettings.failedToConfigure": { + "defaultMessage": "Не удалось настроить учетные данные: {error}" + }, + "authSettings.failedToDelete": { + "defaultMessage": "Не удалось удалить учетные данные: {error}" + }, + "authSettings.failedToLoad": { + "defaultMessage": "Не удалось загрузить учетные данные провайдера" + }, + "authSettings.loading": { + "defaultMessage": "Загрузка учетных данных..." + }, + "authSettings.reauthorize": { + "defaultMessage": "Авторизоваться снова" + }, + "authSettings.signIn": { + "defaultMessage": "Войти" + }, + "authSettings.signedIn": { + "defaultMessage": "Учетные данные настроены" + }, + "authSettings.storageProviderCache": { + "defaultMessage": "Кэш провайдера" + }, + "authSettings.storageSecretStore": { + "defaultMessage": "Хранилище секретов" + }, + "authSettings.title": { + "defaultMessage": "Учетные данные провайдера" + }, "backButton.back": { "defaultMessage": "Назад" }, @@ -1457,6 +1517,21 @@ "huggingFaceModelSearch.tooLarge": { "defaultMessage": "Может не поместиться в память (модель {size}, доступно {available})" }, + "huggingFaceSignInPrompt.failedToConfigure": { + "defaultMessage": "Не удалось войти в Hugging Face: {error}" + }, + "huggingFaceSignInPrompt.signIn": { + "defaultMessage": "Войти" + }, + "huggingFaceSignInPrompt.signedIn": { + "defaultMessage": "Вход в Hugging Face выполнен" + }, + "huggingFaceSignInPrompt.signingIn": { + "defaultMessage": "Выполняется вход..." + }, + "huggingFaceSignInPrompt.title": { + "defaultMessage": "Hugging Face" + }, "imagePreview.altText": { "defaultMessage": "изображение goose" }, @@ -1796,6 +1871,9 @@ "localInferenceSettings.featuredModels": { "defaultMessage": "Рекомендуемые модели" }, + "localInferenceSettings.huggingFaceSignInNote": { + "defaultMessage": "Войдите, чтобы увеличить лимиты запросов при поиске и загрузке моделей, а также получить доступ к приватным или ограниченным репозиториям Hugging Face." + }, "localInferenceSettings.modelSettings": { "defaultMessage": "Настройки модели" }, @@ -2174,24 +2252,6 @@ "modelSettingsPanel.batchSizeDescription": { "defaultMessage": "Пакет обработки промпта" }, - "modelSettingsPanel.contextAndGeneration": { - "defaultMessage": "Контекст и генерация" - }, - "modelSettingsPanel.contextSize": { - "defaultMessage": "Размер контекста" - }, - "modelSettingsPanel.contextSizeDescription": { - "defaultMessage": "Максимальное контекстное окно (0 = по умолчанию модели)" - }, - "modelSettingsPanel.etaLearningRate": { - "defaultMessage": "Eta (скорость обучения)" - }, - "modelSettingsPanel.flashAttention": { - "defaultMessage": "Flash attention" - }, - "modelSettingsPanel.flashAttentionDescription": { - "defaultMessage": "Включить оптимизацию flash attention" - }, "modelSettingsPanel.builtinChatTemplate": { "defaultMessage": "Встроенный шаблон" }, @@ -2213,26 +2273,29 @@ "modelSettingsPanel.chatTemplateEmbedded": { "defaultMessage": "Встроенный" }, + "modelSettingsPanel.contextAndGeneration": { + "defaultMessage": "Контекст и генерация" + }, + "modelSettingsPanel.contextSize": { + "defaultMessage": "Размер контекста" + }, + "modelSettingsPanel.contextSizeDescription": { + "defaultMessage": "Максимальное контекстное окно (0 = по умолчанию модели)" + }, "modelSettingsPanel.customChatTemplate": { "defaultMessage": "Пользовательский шаблон чата" }, "modelSettingsPanel.customChatTemplateDescription": { "defaultMessage": "Вставьте полный исходный код шаблона Jinja" }, - "modelSettingsPanel.toolCalling": { - "defaultMessage": "Вызов инструментов" + "modelSettingsPanel.etaLearningRate": { + "defaultMessage": "Eta (скорость обучения)" }, - "modelSettingsPanel.toolCallingAuto": { - "defaultMessage": "Авто" + "modelSettingsPanel.flashAttention": { + "defaultMessage": "Flash attention" }, - "modelSettingsPanel.toolCallingDescription": { - "defaultMessage": "Выберите, как локальные модели используют нативный или эмулируемый вызов инструментов" - }, - "modelSettingsPanel.toolCallingForceEmulated": { - "defaultMessage": "Принудительно эмулируемый" - }, - "modelSettingsPanel.toolCallingForceNative": { - "defaultMessage": "Принудительно нативный" + "modelSettingsPanel.flashAttentionDescription": { + "defaultMessage": "Включить оптимизацию flash attention" }, "modelSettingsPanel.frequencyPenalty": { "defaultMessage": "Штраф частоты" @@ -2315,6 +2378,21 @@ "modelSettingsPanel.threadsDescription": { "defaultMessage": "Потоки CPU для генерации" }, + "modelSettingsPanel.toolCalling": { + "defaultMessage": "Вызов инструментов" + }, + "modelSettingsPanel.toolCallingAuto": { + "defaultMessage": "Авто" + }, + "modelSettingsPanel.toolCallingDescription": { + "defaultMessage": "Выберите, как локальные модели используют нативный или эмулируемый вызов инструментов" + }, + "modelSettingsPanel.toolCallingForceEmulated": { + "defaultMessage": "Принудительно эмулируемый" + }, + "modelSettingsPanel.toolCallingForceNative": { + "defaultMessage": "Принудительно нативный" + }, "modelSettingsPanel.topK": { "defaultMessage": "Top K" }, @@ -2792,6 +2870,9 @@ "providerConfigurationModal.goBack": { "defaultMessage": "Назад" }, + "providerConfigurationModal.huggingFaceOAuthDescription": { + "defaultMessage": "Войдите, чтобы использовать Hugging Face Inference Providers без ручного ввода API-токена." + }, "providerConfigurationModal.oauthLoginFailed": { "defaultMessage": "Вход OAuth не удался: {error}" }, @@ -3650,6 +3731,9 @@ "securityToggle.mlTokenDescription": { "defaultMessage": "Токен аутентификации для ML-сервиса (например, токен HuggingFace)" }, + "securityToggle.overrideNotice": { + "defaultMessage": "Этот параметр управляется вашей организацией и не может быть изменен." + }, "securityToggle.promptInjectionDescription": { "defaultMessage": "Обнаруживать и предотвращать потенциальные атаки prompt injection" }, @@ -3659,6 +3743,9 @@ "securityToggle.thresholdDescription": { "defaultMessage": "Чем выше значение, тем строже проверка (0.01 = очень мягко, 1.0 = максимально строго)" }, + "securityToggle.warpNotice": { + "defaultMessage": "Обнаружение внедрения команд работает лучше всего при подключении к WARP (требуется для доступа к сервису классификации)." + }, "sessionHistory.cancel": { "defaultMessage": "Отмена" }, @@ -3842,9 +3929,6 @@ "sessions.error.tryAgain": { "defaultMessage": "Повторить попытку" }, - "sessions.extensions": { - "defaultMessage": "Расширения:" - }, "sessions.import": { "defaultMessage": "Импортировать сеанс" }, @@ -4043,6 +4127,9 @@ "settingsView.tabApp": { "defaultMessage": "Приложение" }, + "settingsView.tabAuth": { + "defaultMessage": "Авторизация" + }, "settingsView.tabChat": { "defaultMessage": "Чат" }, diff --git a/ui/desktop/src/i18n/messages/tr.json b/ui/desktop/src/i18n/messages/tr.json index ad2ea8c68..f993fdb2a 100644 --- a/ui/desktop/src/i18n/messages/tr.json +++ b/ui/desktop/src/i18n/messages/tr.json @@ -11,9 +11,6 @@ "announcementModal.gotIt": { "defaultMessage": "Anladım!" }, - "appLayout.closeNavigation": { - "defaultMessage": "Gezinmeyi kapat" - }, "appLayout.openNavigation": { "defaultMessage": "Gezinmeyi aç" }, @@ -47,6 +44,66 @@ "appsView.title": { "defaultMessage": "Uygulamalar" }, + "authSettings.activeProviderWarning": { + "defaultMessage": "Bu etkin sağlayıcıdır. Başka bir kimlik bilgisi yapılandırana kadar yeni istekler başarısız olabilir." + }, + "authSettings.cancel": { + "defaultMessage": "İptal" + }, + "authSettings.delete": { + "defaultMessage": "Sil" + }, + "authSettings.deleteCredential": { + "defaultMessage": "Kimlik bilgisini sil" + }, + "authSettings.deleteMessage": { + "defaultMessage": "{provider} için {name} kimlik bilgisi silinsin mi?" + }, + "authSettings.deleteTitle": { + "defaultMessage": "Kimlik bilgisini sil" + }, + "authSettings.deleted": { + "defaultMessage": "Kimlik bilgisi silindi" + }, + "authSettings.description": { + "defaultMessage": "goose tarafından yerel olarak saklanan sağlayıcı kimlik bilgilerini yönetin." + }, + "authSettings.empty": { + "defaultMessage": "Yerel olarak saklanan sağlayıcı kimlik bilgisi bulunamadı." + }, + "authSettings.expiresAt": { + "defaultMessage": "{date} tarihinde sona erer" + }, + "authSettings.failedToConfigure": { + "defaultMessage": "Kimlik bilgisi yapılandırılamadı: {error}" + }, + "authSettings.failedToDelete": { + "defaultMessage": "Kimlik bilgisi silinemedi: {error}" + }, + "authSettings.failedToLoad": { + "defaultMessage": "Sağlayıcı kimlik bilgileri yüklenemedi" + }, + "authSettings.loading": { + "defaultMessage": "Kimlik bilgileri yükleniyor..." + }, + "authSettings.reauthorize": { + "defaultMessage": "Yeniden yetkilendir" + }, + "authSettings.signIn": { + "defaultMessage": "Oturum aç" + }, + "authSettings.signedIn": { + "defaultMessage": "Kimlik bilgisi yapılandırıldı" + }, + "authSettings.storageProviderCache": { + "defaultMessage": "Sağlayıcı önbelleği" + }, + "authSettings.storageSecretStore": { + "defaultMessage": "Gizli anahtar deposu" + }, + "authSettings.title": { + "defaultMessage": "Sağlayıcı Kimlik Bilgileri" + }, "backButton.back": { "defaultMessage": "Geri" }, @@ -110,24 +167,6 @@ "chat.notification.taskComplete.title": { "defaultMessage": "Goose görevi tamamladı." }, - "chatHistorySearch.keyboardHintMac": { - "defaultMessage": "⌘K" - }, - "chatHistorySearch.keyboardHintOther": { - "defaultMessage": "Ctrl+K" - }, - "chatHistorySearch.messageCount": { - "defaultMessage": "{count,plural,one{# mesaj} other{# mesaj}}" - }, - "chatHistorySearch.noResults": { - "defaultMessage": "Sohbet bulunamadı" - }, - "chatHistorySearch.searchError": { - "defaultMessage": "Arama başarısız oldu" - }, - "chatHistorySearch.searchPlaceholder": { - "defaultMessage": "Sohbetlerde ara…" - }, "chatInput.contextWindow": { "defaultMessage": "Bağlam penceresi" }, @@ -182,12 +221,6 @@ "chatInput.waitingForImages": { "defaultMessage": "Resimlerin kaydedilmesi bekleniyor..." }, - "chatSessionsDropdown.newChat": { - "defaultMessage": "Yeni Sohbet" - }, - "chatSessionsDropdown.showAll": { - "defaultMessage": "Tümünü Göster" - }, "chatSettings.modeDescription": { "defaultMessage": "Goose'nin araçlar ve uzantılarla nasıl etkileşimde bulunacağını yapılandırın" }, @@ -200,9 +233,6 @@ "chatSettings.responseStylesTitle": { "defaultMessage": "Yanıt Stilleri" }, - "condensedRenderer.newChat": { - "defaultMessage": "Yeni Sohbet" - }, "configSettings.configReset": { "defaultMessage": "Yapılandırma Sıfırlama" }, @@ -1382,63 +1412,6 @@ "goosehintsSection.title": { "defaultMessage": "Proje İpuçları (.goosehints)" }, - "greeting.readyToBuild": { - "defaultMessage": "Harika bir şey inşa etmeye hazır mısınız?" - }, - "greeting.readyToCreateGreat": { - "defaultMessage": "Harika bir şey yaratmaya hazır mısınız?" - }, - "greeting.readyToGetStarted": { - "defaultMessage": "Başlamaya hazır mısınız?" - }, - "greeting.whatCanBeAchieved": { - "defaultMessage": "Ne başarılabilir?" - }, - "greeting.whatCanBeBuilt": { - "defaultMessage": "Bugün ne inşa edilebilir?" - }, - "greeting.whatNeedsToBeDone": { - "defaultMessage": "Ne yapılması gerekiyor?" - }, - "greeting.whatProgress": { - "defaultMessage": "Hangi ilerleme kaydedilebilir?" - }, - "greeting.whatProjectNeedsAttention": { - "defaultMessage": "Hangi projenin ilgiye ihtiyacı var?" - }, - "greeting.whatProjectReadyToBegin": { - "defaultMessage": "Hangi proje başlamaya hazır?" - }, - "greeting.whatShallWeCreate": { - "defaultMessage": "Bugün ne yaratacağız?" - }, - "greeting.whatTaskAwaits": { - "defaultMessage": "Hangi görev bekliyor?" - }, - "greeting.whatToAccomplish": { - "defaultMessage": "Neyi başarmak istersiniz?" - }, - "greeting.whatToExplore": { - "defaultMessage": "Neyi keşfetmek istersiniz?" - }, - "greeting.whatToTackle": { - "defaultMessage": "Neyle uğraşmak istersin?" - }, - "greeting.whatToWorkOn": { - "defaultMessage": "Ne üzerinde çalışmak istersin?" - }, - "greeting.whatsNextChallenge": { - "defaultMessage": "Bir sonraki zorluk nedir?" - }, - "greeting.whatsOnYourMind": { - "defaultMessage": "Aklında ne var?" - }, - "greeting.whatsTheMission": { - "defaultMessage": "Bugünkü görev nedir?" - }, - "greeting.whatsThePlan": { - "defaultMessage": "Bugünkü planın ne?" - }, "groupedExtensionLoadingToast.askGoose": { "defaultMessage": "goose'a sorun" }, @@ -1499,6 +1472,15 @@ "headersSection.value": { "defaultMessage": "Değer" }, + "hub.goodAfternoon": { + "defaultMessage": "İyi günler" + }, + "hub.goodEvening": { + "defaultMessage": "İyi akşamlar" + }, + "hub.goodMorning": { + "defaultMessage": "Günaydın" + }, "huggingFaceModelSearch.download": { "defaultMessage": "İndir" }, @@ -1535,6 +1517,21 @@ "huggingFaceModelSearch.tooLarge": { "defaultMessage": "Belleğe sığmayabilir ({size} modeli, {available} mevcuttur)" }, + "huggingFaceSignInPrompt.failedToConfigure": { + "defaultMessage": "Hugging Face oturumu açılamadı: {error}" + }, + "huggingFaceSignInPrompt.signIn": { + "defaultMessage": "Oturum aç" + }, + "huggingFaceSignInPrompt.signedIn": { + "defaultMessage": "Hugging Face oturumu açıldı" + }, + "huggingFaceSignInPrompt.signingIn": { + "defaultMessage": "Oturum açılıyor..." + }, + "huggingFaceSignInPrompt.title": { + "defaultMessage": "Hugging Face" + }, "imagePreview.altText": { "defaultMessage": "goose resmi" }, @@ -1874,6 +1871,9 @@ "localInferenceSettings.featuredModels": { "defaultMessage": "Öne Çıkan Modeller" }, + "localInferenceSettings.huggingFaceSignInNote": { + "defaultMessage": "Model ararken ve indirirken hız sınırlarını artırmak ve özel ya da erişimi kısıtlı Hugging Face depolarına erişmek için oturum açın." + }, "localInferenceSettings.modelSettings": { "defaultMessage": "Modeli Ayarları" }, @@ -2252,24 +2252,6 @@ "modelSettingsPanel.batchSizeDescription": { "defaultMessage": "Hızlı işlem toplu" }, - "modelSettingsPanel.contextAndGeneration": { - "defaultMessage": "Bağlam ve Üretim" - }, - "modelSettingsPanel.contextSize": { - "defaultMessage": "Bağlam boyutu" - }, - "modelSettingsPanel.contextSizeDescription": { - "defaultMessage": "Maksimum bağlam penceresi (0 = model varsayılanı)" - }, - "modelSettingsPanel.etaLearningRate": { - "defaultMessage": "Eta (öğrenme oranı)" - }, - "modelSettingsPanel.flashAttention": { - "defaultMessage": "Flaş dikkat" - }, - "modelSettingsPanel.flashAttentionDescription": { - "defaultMessage": "Flaş dikkati optimizasyonunu etkinleştir" - }, "modelSettingsPanel.builtinChatTemplate": { "defaultMessage": "Yerleşik şablon" }, @@ -2291,26 +2273,29 @@ "modelSettingsPanel.chatTemplateEmbedded": { "defaultMessage": "Gömülü" }, + "modelSettingsPanel.contextAndGeneration": { + "defaultMessage": "Bağlam ve Üretim" + }, + "modelSettingsPanel.contextSize": { + "defaultMessage": "Bağlam boyutu" + }, + "modelSettingsPanel.contextSizeDescription": { + "defaultMessage": "Maksimum bağlam penceresi (0 = model varsayılanı)" + }, "modelSettingsPanel.customChatTemplate": { "defaultMessage": "Özel sohbet şablonu" }, "modelSettingsPanel.customChatTemplateDescription": { "defaultMessage": "Tam Jinja sohbet şablonu kaynağını yapıştır" }, - "modelSettingsPanel.toolCalling": { - "defaultMessage": "Araç çağırma" + "modelSettingsPanel.etaLearningRate": { + "defaultMessage": "Eta (öğrenme oranı)" }, - "modelSettingsPanel.toolCallingAuto": { - "defaultMessage": "Otomatik" + "modelSettingsPanel.flashAttention": { + "defaultMessage": "Flaş dikkat" }, - "modelSettingsPanel.toolCallingDescription": { - "defaultMessage": "Yerel modellerin yerel veya emüle araç çağırmayı nasıl seçeceğini belirleyin" - }, - "modelSettingsPanel.toolCallingForceEmulated": { - "defaultMessage": "Emüle etmeye zorla" - }, - "modelSettingsPanel.toolCallingForceNative": { - "defaultMessage": "Yereli zorla" + "modelSettingsPanel.flashAttentionDescription": { + "defaultMessage": "Flaş dikkati optimizasyonunu etkinleştir" }, "modelSettingsPanel.frequencyPenalty": { "defaultMessage": "Frekans cezası" @@ -2393,6 +2378,21 @@ "modelSettingsPanel.threadsDescription": { "defaultMessage": "Nesil için CPU iş parçacıkları" }, + "modelSettingsPanel.toolCalling": { + "defaultMessage": "Araç çağırma" + }, + "modelSettingsPanel.toolCallingAuto": { + "defaultMessage": "Otomatik" + }, + "modelSettingsPanel.toolCallingDescription": { + "defaultMessage": "Yerel modellerin yerel veya emüle araç çağırmayı nasıl seçeceğini belirleyin" + }, + "modelSettingsPanel.toolCallingForceEmulated": { + "defaultMessage": "Emüle etmeye zorla" + }, + "modelSettingsPanel.toolCallingForceNative": { + "defaultMessage": "Yereli zorla" + }, "modelSettingsPanel.topK": { "defaultMessage": "En İyi K" }, @@ -2426,77 +2426,41 @@ "modelsSection.resetTitle": { "defaultMessage": "Sağlayıcıyı ve Modeli Sıfırla" }, - "navigationCustomization.dragInstructions": { - "defaultMessage": "Yeniden sıralamak için sürükleyin, öğeleri göstermek/gizlemek için göz simgesini tıklayın" - }, - "navigationCustomization.hideItem": { - "defaultMessage": "Öğeyi gizle" - }, - "navigationCustomization.itemApps": { + "navigation.itemApps": { "defaultMessage": "Uygulamalar" }, - "navigationCustomization.itemChat": { - "defaultMessage": "Sohbet" - }, - "navigationCustomization.itemExtensions": { + "navigation.itemExtensions": { "defaultMessage": "Uzantılar" }, - "navigationCustomization.itemHome": { - "defaultMessage": "Ana sayfa" + "navigation.itemHome": { + "defaultMessage": "Yeni Sohbet" }, - "navigationCustomization.itemRecipes": { + "navigation.itemRecipes": { "defaultMessage": "Tarifler" }, - "navigationCustomization.itemScheduler": { + "navigation.itemScheduler": { "defaultMessage": "Zamanlayıcı" }, - "navigationCustomization.itemSettings": { + "navigation.itemSessions": { + "defaultMessage": "Oturum Geçmişi" + }, + "navigation.itemSettings": { "defaultMessage": "Ayarlar" }, - "navigationCustomization.itemSkills": { + "navigation.itemSkills": { "defaultMessage": "Beceriler" }, - "navigationCustomization.resetToDefaults": { - "defaultMessage": "Varsayılanlara sıfırla" + "navigationPanel.chats": { + "defaultMessage": "Sohbetler" }, - "navigationCustomization.showItem": { - "defaultMessage": "Öğeyi göster" + "navigationPanel.collapseSidebar": { + "defaultMessage": "Kenar çubuğunu daralt" }, - "navigationModeSelector.overlayDescription": { - "defaultMessage": "Tam ekran yer paylaşımı" + "navigationPanel.noChats": { + "defaultMessage": "Son sohbet yok" }, - "navigationModeSelector.overlayLabel": { - "defaultMessage": "Kaplama" - }, - "navigationModeSelector.pushDescription": { - "defaultMessage": "Gezinme içeriği zorlar" - }, - "navigationModeSelector.pushLabel": { - "defaultMessage": "İt" - }, - "navigationPositionSelector.bottomLabel": { - "defaultMessage": "Alt" - }, - "navigationPositionSelector.leftLabel": { - "defaultMessage": "Sol" - }, - "navigationPositionSelector.rightLabel": { - "defaultMessage": "Sağ" - }, - "navigationPositionSelector.topLabel": { - "defaultMessage": "Üst" - }, - "navigationStyleSelector.listDescription": { - "defaultMessage": "Klasik yoğunlaştırılmış görünüm" - }, - "navigationStyleSelector.listLabel": { - "defaultMessage": "Liste" - }, - "navigationStyleSelector.tileDescription": { - "defaultMessage": "Büyütülmüş döşeme görünümü" - }, - "navigationStyleSelector.tileLabel": { - "defaultMessage": "Fayans" + "navigationPanel.untitledSession": { + "defaultMessage": "Başlıksız oturum" }, "onboardingGuard.checkProviderErrorDescription": { "defaultMessage": "Sunucu başlatılıyor veya geçici olarak kullanılamıyor olabilir." @@ -2906,6 +2870,9 @@ "providerConfigurationModal.goBack": { "defaultMessage": "Geri Dön" }, + "providerConfigurationModal.huggingFaceOAuthDescription": { + "defaultMessage": "API belirtecini elle girmeden Hugging Face Inference Providers kullanmak için oturum açın." + }, "providerConfigurationModal.oauthLoginFailed": { "defaultMessage": "OAuth oturum açma işlemi başarısız oldu: {error}" }, @@ -3764,6 +3731,9 @@ "securityToggle.mlTokenDescription": { "defaultMessage": "ML hizmeti için kimlik doğrulama belirteci (ör. HuggingFace belirteci)" }, + "securityToggle.overrideNotice": { + "defaultMessage": "Bu ayar kuruluşunuz tarafından yönetiliyor ve değiştirilemez." + }, "securityToggle.promptInjectionDescription": { "defaultMessage": "Potansiyel anlık enjeksiyon saldırılarını tespit edin ve önleyin" }, @@ -3773,6 +3743,9 @@ "securityToggle.thresholdDescription": { "defaultMessage": "Daha yüksek değerler daha katıdır (0,01 = çok yumuşak, 1,0 = maksimum katı)" }, + "securityToggle.warpNotice": { + "defaultMessage": "Komut enjeksiyonu algılama, WARP bağlantısı olduğunda en iyi şekilde çalışır (sınıflandırma hizmetine erişmek için gereklidir)." + }, "sessionHistory.cancel": { "defaultMessage": "İptal" }, @@ -3956,9 +3929,6 @@ "sessions.error.tryAgain": { "defaultMessage": "Tekrar Deneyin" }, - "sessions.extensions": { - "defaultMessage": "Uzantılar:" - }, "sessions.import": { "defaultMessage": "Oturumu İçe Aktar" }, @@ -4037,33 +4007,6 @@ "sessions.toast.updated": { "defaultMessage": "Oturum açıklaması başarıyla güncellendi" }, - "sessionsInsights.failedToLoad": { - "defaultMessage": "Analizler yüklenemedi" - }, - "sessionsInsights.noRecentChats": { - "defaultMessage": "Yeni sohbet oturumu bulunamadı." - }, - "sessionsInsights.recentChats": { - "defaultMessage": "Son sohbetler" - }, - "sessionsInsights.seeAll": { - "defaultMessage": "Tümünü gör" - }, - "sessionsInsights.totalSessions": { - "defaultMessage": "Toplam oturumlar" - }, - "sessionsInsights.totalTokens": { - "defaultMessage": "Toplam jeton" - }, - "sessionsList.showAll": { - "defaultMessage": "Tümünü Göster" - }, - "sessionsList.startNewChat": { - "defaultMessage": "Yeni Sohbet Başlat" - }, - "sessionsList.untitledSession": { - "defaultMessage": "Başlıksız oturum" - }, "sessionsView.error.failedToLoad": { "defaultMessage": "Oturum ayrıntıları yüklenemedi. Lütfen daha sonra tekrar deneyin." }, @@ -4109,24 +4052,6 @@ "settings.menuBarIcon.title": { "defaultMessage": "Menü çubuğu simgesi" }, - "settings.navigation.customize": { - "defaultMessage": "Öğeleri Özelleştir" - }, - "settings.navigation.description": { - "defaultMessage": "Gezinme düzenini ve davranışını özelleştirin" - }, - "settings.navigation.mode": { - "defaultMessage": "Mod" - }, - "settings.navigation.position": { - "defaultMessage": "Pozisyon" - }, - "settings.navigation.style": { - "defaultMessage": "Stil" - }, - "settings.navigation.title": { - "defaultMessage": "Navigasyon" - }, "settings.notifications.configGuide": { "defaultMessage": "Yapılandırma kılavuzu" }, @@ -4202,6 +4127,9 @@ "settingsView.tabApp": { "defaultMessage": "Uygulama" }, + "settingsView.tabAuth": { + "defaultMessage": "Kimlik Doğrulama" + }, "settingsView.tabChat": { "defaultMessage": "Sohbet" }, diff --git a/ui/desktop/src/i18n/messages/zh-CN.json b/ui/desktop/src/i18n/messages/zh-CN.json index 45677612b..66578ed21 100644 --- a/ui/desktop/src/i18n/messages/zh-CN.json +++ b/ui/desktop/src/i18n/messages/zh-CN.json @@ -44,6 +44,66 @@ "appsView.title": { "defaultMessage": "应用" }, + "authSettings.activeProviderWarning": { + "defaultMessage": "这是当前正在使用的提供商。在配置其他凭据之前,新的请求可能会失败。" + }, + "authSettings.cancel": { + "defaultMessage": "取消" + }, + "authSettings.delete": { + "defaultMessage": "删除" + }, + "authSettings.deleteCredential": { + "defaultMessage": "删除凭据" + }, + "authSettings.deleteMessage": { + "defaultMessage": "要删除 {provider} 的 {name} 凭据吗?" + }, + "authSettings.deleteTitle": { + "defaultMessage": "删除凭据" + }, + "authSettings.deleted": { + "defaultMessage": "凭据已删除" + }, + "authSettings.description": { + "defaultMessage": "管理 goose 在本地存储的提供商凭据。" + }, + "authSettings.empty": { + "defaultMessage": "未找到本地存储的提供商凭据。" + }, + "authSettings.expiresAt": { + "defaultMessage": "到期时间:{date}" + }, + "authSettings.failedToConfigure": { + "defaultMessage": "配置凭据失败:{error}" + }, + "authSettings.failedToDelete": { + "defaultMessage": "删除凭据失败:{error}" + }, + "authSettings.failedToLoad": { + "defaultMessage": "加载提供商凭据失败" + }, + "authSettings.loading": { + "defaultMessage": "正在加载凭据..." + }, + "authSettings.reauthorize": { + "defaultMessage": "重新授权" + }, + "authSettings.signIn": { + "defaultMessage": "登录" + }, + "authSettings.signedIn": { + "defaultMessage": "凭据已配置" + }, + "authSettings.storageProviderCache": { + "defaultMessage": "提供商缓存" + }, + "authSettings.storageSecretStore": { + "defaultMessage": "密钥存储" + }, + "authSettings.title": { + "defaultMessage": "提供商凭据" + }, "backButton.back": { "defaultMessage": "返回" }, @@ -497,12 +557,21 @@ "cronPicker.august": { "defaultMessage": "八月" }, + "cronPicker.cronExpression": { + "defaultMessage": "Cron 表达式" + }, + "cronPicker.custom": { + "defaultMessage": "自定义 cron" + }, "cronPicker.day": { "defaultMessage": "日" }, "cronPicker.december": { "defaultMessage": "十二月" }, + "cronPicker.emptyCronError": { + "defaultMessage": "Cron 表达式不能为空" + }, "cronPicker.every": { "defaultMessage": "每" }, @@ -518,6 +587,9 @@ "cronPicker.inMonth": { "defaultMessage": "于" }, + "cronPicker.invalidDayOfMonth": { + "defaultMessage": "日期必须在 1 到 {max} 之间" + }, "cronPicker.january": { "defaultMessage": "一月" }, @@ -536,6 +608,9 @@ "cronPicker.minute": { "defaultMessage": "分" }, + "cronPicker.mode": { + "defaultMessage": "模式" + }, "cronPicker.monday": { "defaultMessage": "周一" }, @@ -554,12 +629,18 @@ "cronPicker.onDay": { "defaultMessage": "于第几日" }, + "cronPicker.quarter": { + "defaultMessage": "季度" + }, "cronPicker.saturday": { "defaultMessage": "周六" }, "cronPicker.september": { "defaultMessage": "九月" }, + "cronPicker.startingMonth": { + "defaultMessage": "起始月份" + }, "cronPicker.sunday": { "defaultMessage": "周日" }, @@ -875,9 +956,30 @@ "dictationSettings.voiceDictationProvider": { "defaultMessage": "语音输入提供商" }, + "dirSwitcher.chooseDirectory": { + "defaultMessage": "选择目录…" + }, + "dirSwitcher.currentDirectory": { + "defaultMessage": "当前目录" + }, "dirSwitcher.failedToUpdateWorkingDir": { "defaultMessage": "更新工作目录失败" }, + "dirSwitcher.gitWorktrees": { + "defaultMessage": "Git 工作树" + }, + "dirSwitcher.noWorktreesFound": { + "defaultMessage": "未找到工作树" + }, + "dirSwitcher.openInFinder": { + "defaultMessage": "在文件管理器中打开" + }, + "dirSwitcher.recentDirectories": { + "defaultMessage": "最近的目录" + }, + "elicitationRequest.accept": { + "defaultMessage": "接受" + }, "elicitationRequest.cancelled": { "defaultMessage": "信息请求已取消。" }, @@ -1370,6 +1472,15 @@ "headersSection.value": { "defaultMessage": "值" }, + "hub.goodAfternoon": { + "defaultMessage": "下午好" + }, + "hub.goodEvening": { + "defaultMessage": "晚上好" + }, + "hub.goodMorning": { + "defaultMessage": "早上好" + }, "huggingFaceModelSearch.download": { "defaultMessage": "下载" }, @@ -1406,6 +1517,21 @@ "huggingFaceModelSearch.tooLarge": { "defaultMessage": "可能超出内存(模型 {size},可用 {available})" }, + "huggingFaceSignInPrompt.failedToConfigure": { + "defaultMessage": "登录 Hugging Face 失败:{error}" + }, + "huggingFaceSignInPrompt.signIn": { + "defaultMessage": "登录" + }, + "huggingFaceSignInPrompt.signedIn": { + "defaultMessage": "已登录 Hugging Face" + }, + "huggingFaceSignInPrompt.signingIn": { + "defaultMessage": "正在登录..." + }, + "huggingFaceSignInPrompt.title": { + "defaultMessage": "Hugging Face" + }, "imagePreview.altText": { "defaultMessage": "goose 图片" }, @@ -1745,6 +1871,9 @@ "localInferenceSettings.featuredModels": { "defaultMessage": "推荐模型" }, + "localInferenceSettings.huggingFaceSignInNote": { + "defaultMessage": "登录后可在搜索和下载模型时提高速率限制,并访问私有或受限的 Hugging Face 仓库。" + }, "localInferenceSettings.modelSettings": { "defaultMessage": "模型设置" }, @@ -2123,24 +2252,6 @@ "modelSettingsPanel.batchSizeDescription": { "defaultMessage": "提示词处理批大小" }, - "modelSettingsPanel.contextAndGeneration": { - "defaultMessage": "上下文与生成" - }, - "modelSettingsPanel.contextSize": { - "defaultMessage": "上下文大小" - }, - "modelSettingsPanel.contextSizeDescription": { - "defaultMessage": "最大上下文窗口(0 = 模型默认)" - }, - "modelSettingsPanel.etaLearningRate": { - "defaultMessage": "Eta(学习率)" - }, - "modelSettingsPanel.flashAttention": { - "defaultMessage": "Flash Attention" - }, - "modelSettingsPanel.flashAttentionDescription": { - "defaultMessage": "启用 Flash Attention 优化" - }, "modelSettingsPanel.builtinChatTemplate": { "defaultMessage": "内置模板" }, @@ -2162,26 +2273,29 @@ "modelSettingsPanel.chatTemplateEmbedded": { "defaultMessage": "嵌入式" }, + "modelSettingsPanel.contextAndGeneration": { + "defaultMessage": "上下文与生成" + }, + "modelSettingsPanel.contextSize": { + "defaultMessage": "上下文大小" + }, + "modelSettingsPanel.contextSizeDescription": { + "defaultMessage": "最大上下文窗口(0 = 模型默认)" + }, "modelSettingsPanel.customChatTemplate": { "defaultMessage": "自定义聊天模板" }, "modelSettingsPanel.customChatTemplateDescription": { "defaultMessage": "粘贴完整的 Jinja 聊天模板源码" }, - "modelSettingsPanel.toolCalling": { - "defaultMessage": "工具调用" + "modelSettingsPanel.etaLearningRate": { + "defaultMessage": "Eta(学习率)" }, - "modelSettingsPanel.toolCallingAuto": { - "defaultMessage": "自动" + "modelSettingsPanel.flashAttention": { + "defaultMessage": "Flash Attention" }, - "modelSettingsPanel.toolCallingDescription": { - "defaultMessage": "选择本地模型如何使用原生或模拟工具调用" - }, - "modelSettingsPanel.toolCallingForceEmulated": { - "defaultMessage": "强制模拟" - }, - "modelSettingsPanel.toolCallingForceNative": { - "defaultMessage": "强制原生" + "modelSettingsPanel.flashAttentionDescription": { + "defaultMessage": "启用 Flash Attention 优化" }, "modelSettingsPanel.frequencyPenalty": { "defaultMessage": "频率惩罚" @@ -2264,6 +2378,21 @@ "modelSettingsPanel.threadsDescription": { "defaultMessage": "用于生成的 CPU 线程数" }, + "modelSettingsPanel.toolCalling": { + "defaultMessage": "工具调用" + }, + "modelSettingsPanel.toolCallingAuto": { + "defaultMessage": "自动" + }, + "modelSettingsPanel.toolCallingDescription": { + "defaultMessage": "选择本地模型如何使用原生或模拟工具调用" + }, + "modelSettingsPanel.toolCallingForceEmulated": { + "defaultMessage": "强制模拟" + }, + "modelSettingsPanel.toolCallingForceNative": { + "defaultMessage": "强制原生" + }, "modelSettingsPanel.topK": { "defaultMessage": "Top K" }, @@ -2312,12 +2441,27 @@ "navigation.itemScheduler": { "defaultMessage": "调度" }, + "navigation.itemSessions": { + "defaultMessage": "会话历史" + }, "navigation.itemSettings": { "defaultMessage": "设置" }, "navigation.itemSkills": { "defaultMessage": "技能" }, + "navigationPanel.chats": { + "defaultMessage": "聊天" + }, + "navigationPanel.collapseSidebar": { + "defaultMessage": "折叠侧边栏" + }, + "navigationPanel.noChats": { + "defaultMessage": "没有最近的聊天" + }, + "navigationPanel.untitledSession": { + "defaultMessage": "未命名会话" + }, "onboardingGuard.checkProviderErrorDescription": { "defaultMessage": "服务器可能正在启动或暂时不可用。" }, @@ -2726,6 +2870,9 @@ "providerConfigurationModal.goBack": { "defaultMessage": "返回" }, + "providerConfigurationModal.huggingFaceOAuthDescription": { + "defaultMessage": "登录后即可使用 Hugging Face Inference Providers,而无需手动输入 API 令牌。" + }, "providerConfigurationModal.oauthLoginFailed": { "defaultMessage": "OAuth 登录失败:{error}" }, @@ -3584,6 +3731,9 @@ "securityToggle.mlTokenDescription": { "defaultMessage": "机器学习服务的认证令牌(例如 HuggingFace token)" }, + "securityToggle.overrideNotice": { + "defaultMessage": "此设置由你的组织管理,无法更改。" + }, "securityToggle.promptInjectionDescription": { "defaultMessage": "检测并防范潜在的提示注入攻击" }, @@ -3593,6 +3743,9 @@ "securityToggle.thresholdDescription": { "defaultMessage": "值越高越严格(0.01 = 非常宽松,1.0 = 最严格)" }, + "securityToggle.warpNotice": { + "defaultMessage": "连接到 WARP 时,命令注入检测效果最佳(访问分类服务需要 WARP)。" + }, "sessionHistory.cancel": { "defaultMessage": "取消" }, @@ -3737,6 +3890,9 @@ "sessions.action.openNewWindow": { "defaultMessage": "在新窗口中打开" }, + "sessions.action.shareNostr": { + "defaultMessage": "分享加密的 Nostr 链接" + }, "sessions.cancel": { "defaultMessage": "取消" }, @@ -3746,6 +3902,9 @@ "sessions.chatHistoryDesc": { "defaultMessage": "查看并搜索你与 Goose 的过往对话。按 {shortcut} 搜索。" }, + "sessions.close": { + "defaultMessage": "关闭" + }, "sessions.delete.message": { "defaultMessage": "确定要删除会话“{name}”吗?此操作无法撤销。" }, @@ -3770,12 +3929,24 @@ "sessions.error.tryAgain": { "defaultMessage": "重试" }, - "sessions.extensions": { - "defaultMessage": "扩展:" - }, "sessions.import": { "defaultMessage": "导入会话" }, + "sessions.importNostr": { + "defaultMessage": "导入链接" + }, + "sessions.importNostr.description": { + "defaultMessage": "粘贴 Goose Nostr 分享链接以获取、解密并导入会话。" + }, + "sessions.importNostr.placeholder": { + "defaultMessage": "goose://sessions/nostr?nevent=...&key=..." + }, + "sessions.importNostr.title": { + "defaultMessage": "导入 Nostr 会话" + }, + "sessions.importing": { + "defaultMessage": "正在导入..." + }, "sessions.loadingMore": { "defaultMessage": "正在加载更多会话…" }, @@ -3794,6 +3965,15 @@ "sessions.searchPlaceholder": { "defaultMessage": "搜索历史…" }, + "sessions.shareNostr.description": { + "defaultMessage": "任何拥有此链接的人都可以获取并解密该会话。请像对待密钥一样保护它。" + }, + "sessions.shareNostr.title": { + "defaultMessage": "加密的 Nostr 分享链接" + }, + "sessions.toast.copied": { + "defaultMessage": "已复制到剪贴板" + }, "sessions.toast.deleteFailed": { "defaultMessage": "删除会话“{name}”失败:{error}" }, @@ -3815,6 +3995,12 @@ "sessions.toast.imported": { "defaultMessage": "会话导入成功" }, + "sessions.toast.shareNostr": { + "defaultMessage": "已创建加密的 Nostr 分享链接" + }, + "sessions.toast.shareNostrFailed": { + "defaultMessage": "创建 Nostr 分享链接失败:{error}" + }, "sessions.toast.updateFailed": { "defaultMessage": "更新会话描述失败:{error}" }, @@ -3941,6 +4127,9 @@ "settingsView.tabApp": { "defaultMessage": "应用" }, + "settingsView.tabAuth": { + "defaultMessage": "身份验证" + }, "settingsView.tabChat": { "defaultMessage": "聊天" }, @@ -4241,6 +4430,9 @@ "switchModelModal.thinkingEffort": { "defaultMessage": "思考努力" }, + "switchModelModal.thinkingEffortOff": { + "defaultMessage": "关闭 - 不使用扩展思考" + }, "switchModelModal.thinkingLevel": { "defaultMessage": "思考级别" }, diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml index 144d984ba..7edfc2ce7 100644 --- a/ui/pnpm-lock.yaml +++ b/ui/pnpm-lock.yaml @@ -226,6 +226,9 @@ importers: '@formatjs/cli': specifier: ^6.14.0 version: 6.14.0 + '@formatjs/icu-messageformat-parser': + specifier: 3.5.3 + version: 3.5.3 '@hey-api/openapi-ts': specifier: ^0.93.0 version: 0.93.1(magicast@0.5.2)(typescript@5.9.3)