feat(voice): first-class voice input and local TTS across web, desktop, and mobile (#2018)
Complete rebuild of voice input on a server-authoritative streaming architecture, replacing the legacy Web Speech / whole-blob / WASM engines and the dead voice-agent layer (~4k lines removed). Speech-to-text (dictation): - Client streams 16 kHz mono PCM16 chunks over /api/dictation/ws with seq/ack ordering; buffered audio is retained and replayed on reconnect - Server transcribes and streams live partial transcripts back; segments auto-commit every ~15s with silence suppression and adaptive finalization timeouts - Local provider (default, zero config): sherpa-onnx models in a forked worker process — auto-download with progress, staged extraction with verification, corrupt-model auto-recovery, idle shutdown after 5 min - Model catalog with settings picker (accuracy/speed ratings, sizes, download/delete): Parakeet TDT v2 (English) and v3 (25 European languages, auto-detected), Whisper base and tiny (multilingual, light) - OpenAI-compatible provider for any Whisper endpoint - Composer overlay with live transcript, volume meter, timer, and cancel / insert / insert-and-send actions; failed transcriptions keep their audio for retry or accepting the partial text as-is - Configurable keyboard shortcut (default mod+alt+v) toggles dictation; Enter confirms and Escape cancels while recording - Overlay is pixel-aligned with the composer (measured footer height, matching paddings/typography/gaps) — no layout shift when toggling Text-to-speech: - Local Kokoro provider (English, 11 voices) synthesized in the same worker via /api/dictation/tts/speak, managed by the shared model pipeline; sentence-pipelined playback keeps time-to-first-audio at ~1 sentence regardless of message length, and stop cancels in-flight synthesis - Sanitizer keeps inline-code content (strips backticks only), reads interword slashes aloud, and removes only absolute file paths Settings: - Voice page unified: a single read-aloud toggle owns all playback options (the confusing "Enable Voice Mode" is gone); a new "Enable voice input" toggle (default on, persisted to settings.json) hides the composer mic entirely when disabled Mobile and transport: - iOS/Android microphone permissions added (dictation was previously impossible on mobile) - Fixed Android WebSocket upgrades: the Capacitor WebView origin (https://localhost) was missing from the packaged-client allowlist, 403-ing every WS connection — root cause of the old mobile SSE lock, which is now removed for all transports Security and conventions: - All HTTP routes sit behind the global /api auth gate; the WS upgrade explicitly validates the UI session and origin, with oc_url_token narrowly allowlisted and covered by tests; the dictation socket mints a fresh URL token before connecting - Routes register before the generic OpenCode proxy; the client goes through runtimeFetch/getRuntimeUrlResolver, and runtime switches reset the dictation socket - VS Code deliberately reports dictation as unavailable (no server process in that runtime) CI: workflow Node bumped 20 -> 22 to match the repo engines and fix better-sqlite3 installs broken by node-gyp@latest on Node 20. New dependency: sherpa-onnx-node (prebuilt N-API; macOS/Linux x64+arm64, Windows x64 — Windows-on-ARM falls back to the OpenAI-compatible provider)
This commit is contained in:
committed by
GitHub
parent
3f5151d424
commit
de1b85ac56
@@ -1518,16 +1518,33 @@ export const settingsDict = {
|
||||
'settings.notifications.page.toast.backgroundDisabled': 'Background notifications disabled',
|
||||
'settings.notifications.page.testNotification.title': 'Test Notification',
|
||||
'settings.notifications.page.testNotification.body': 'This is a test notification from OpenChamber.',
|
||||
'settings.voice.page.section.voiceSetup': 'Voice Setup',
|
||||
'settings.voice.page.section.speechRecognition': 'Speech Recognition',
|
||||
'settings.voice.page.field.enableVoiceInput': 'Enable voice input',
|
||||
'settings.voice.page.field.enableVoiceInputAria': 'Enable voice input (dictation)',
|
||||
'settings.voice.page.section.playbackAndSummary': 'Playback',
|
||||
'settings.voice.page.field.enableVoiceModeAria': 'Enable voice mode',
|
||||
'settings.voice.page.field.enableVoiceMode': 'Enable Voice Mode',
|
||||
'settings.voice.page.field.provider': 'Provider',
|
||||
'settings.voice.page.provider.browser': 'Browser',
|
||||
'settings.voice.page.provider.custom': 'Custom',
|
||||
'settings.voice.page.provider.say': 'Say',
|
||||
'settings.voice.page.provider.server': 'Server',
|
||||
'settings.voice.page.provider.local': 'Local',
|
||||
'settings.voice.page.tooltip.sttLocal': 'On-device transcription on the OpenChamber server. Models download automatically; no API key needed.',
|
||||
'settings.voice.page.tooltip.localTts': 'On-device synthesis on the OpenChamber server (Kokoro, English). The model downloads automatically; no API key needed.',
|
||||
'settings.voice.page.stt.model.parakeetV2': 'Parakeet v2 (English)',
|
||||
'settings.voice.page.stt.model.parakeetV3': 'Parakeet v3 (25 European languages)',
|
||||
'settings.voice.page.stt.model.whisperBase': 'Whisper base (multilingual)',
|
||||
'settings.voice.page.stt.model.whisperTiny': 'Whisper tiny (multilingual)',
|
||||
'settings.voice.page.stt.badge.bestForEnglish': 'Best for English',
|
||||
'settings.voice.page.stt.badge.bestForMultilingual': 'Best for multilingual',
|
||||
'settings.voice.page.stt.meta.accuracy': 'Accuracy',
|
||||
'settings.voice.page.stt.meta.speed': 'Speed',
|
||||
'settings.voice.page.stt.modelInstalled': 'Model installed',
|
||||
'settings.voice.page.stt.modelDownloading': 'Downloading model...',
|
||||
'settings.voice.page.stt.modelDownloadingProgress': 'Downloading model... {percent}%',
|
||||
'settings.voice.page.stt.modelNotInstalled': 'Model not downloaded',
|
||||
'settings.voice.page.stt.modelDownload': 'Download',
|
||||
'settings.voice.page.stt.modelDelete': 'Delete model',
|
||||
'settings.voice.page.stt.modelRetry': 'Retry',
|
||||
'settings.voice.page.provider.wasm': 'Local',
|
||||
'settings.voice.page.stt.wasmModel': 'Whisper Model',
|
||||
'settings.voice.page.stt.wasmLoaded': 'Model loaded, ready',
|
||||
|
||||
@@ -1873,6 +1873,18 @@ export const dict = {
|
||||
'chat.chatInput.placeholder.chat': '@ for files/agents; / for commands and skills; ! for shell; # for snippets',
|
||||
'chat.chatInput.placeholder.chatCompact': 'Use @ / ! # for helpers',
|
||||
'chat.chatInput.placeholder.selectSession': 'Select or create a session to start chatting',
|
||||
'chat.dictation.start': 'Start dictation',
|
||||
'chat.dictation.overlayAria': 'Dictation',
|
||||
'chat.dictation.downloadingModel': 'Downloading speech model...',
|
||||
'chat.dictation.downloadingModelProgress': 'Downloading speech model... {percent}%',
|
||||
'chat.dictation.listening': 'Listening...',
|
||||
'chat.dictation.processing': 'Transcribing...',
|
||||
'chat.dictation.failed': 'Transcription failed',
|
||||
'chat.dictation.cancel': 'Discard dictation',
|
||||
'chat.dictation.insert': 'Insert transcript',
|
||||
'chat.dictation.insertAndSend': 'Insert and send',
|
||||
'chat.dictation.retry': 'Retry transcription',
|
||||
'chat.dictation.discard': 'Discard recording',
|
||||
'chat.snippetAutocomplete.action.addNew': '+ Add new snippet',
|
||||
'chat.snippetAutocomplete.empty': 'No snippets found',
|
||||
'chat.snippetAutocomplete.footer': '↑↓ navigate • Enter select • Esc close',
|
||||
|
||||
@@ -1485,16 +1485,33 @@ export const settingsDict = {
|
||||
"settings.notifications.page.toast.backgroundDisabled": "Notificaciones de fondo deshabilitadas",
|
||||
"settings.notifications.page.testNotification.title": "Notificación de prueba",
|
||||
"settings.notifications.page.testNotification.body": "Esta es una notificación de prueba de OpenChamber.",
|
||||
"settings.voice.page.section.voiceSetup": "Configuración de voz",
|
||||
"settings.voice.page.section.speechRecognition": "Reconocimiento de voz",
|
||||
"settings.voice.page.field.enableVoiceInput": "Habilitar entrada de voz",
|
||||
"settings.voice.page.field.enableVoiceInputAria": "Habilitar entrada de voz (dictado)",
|
||||
"settings.voice.page.section.playbackAndSummary": "Reproducción",
|
||||
"settings.voice.page.field.enableVoiceModeAria": "Habilitar modo de voz",
|
||||
"settings.voice.page.field.enableVoiceMode": "Habilitar modo de voz",
|
||||
"settings.voice.page.field.provider": "Proveedor",
|
||||
"settings.voice.page.provider.browser": "Navegador",
|
||||
"settings.voice.page.provider.custom": "Personalizado",
|
||||
"settings.voice.page.provider.say": "Decir",
|
||||
"settings.voice.page.provider.server": "Servidor",
|
||||
"settings.voice.page.provider.local": "Local",
|
||||
"settings.voice.page.tooltip.sttLocal": "Transcripción local en el servidor de OpenChamber. Los modelos se descargan automáticamente; no se necesita clave de API.",
|
||||
"settings.voice.page.tooltip.localTts": "Síntesis local en el servidor de OpenChamber (Kokoro, inglés). El modelo se descarga automáticamente; no se necesita clave de API.",
|
||||
"settings.voice.page.stt.model.parakeetV2": "Parakeet v2 (inglés)",
|
||||
"settings.voice.page.stt.model.parakeetV3": "Parakeet v3 (25 idiomas europeos)",
|
||||
"settings.voice.page.stt.model.whisperBase": "Whisper base (multilingüe)",
|
||||
"settings.voice.page.stt.model.whisperTiny": "Whisper tiny (multilingüe)",
|
||||
"settings.voice.page.stt.badge.bestForEnglish": "Mejor para inglés",
|
||||
"settings.voice.page.stt.badge.bestForMultilingual": "Mejor multilingüe",
|
||||
"settings.voice.page.stt.meta.accuracy": "Precisión",
|
||||
"settings.voice.page.stt.meta.speed": "Velocidad",
|
||||
"settings.voice.page.stt.modelInstalled": "Modelo instalado",
|
||||
"settings.voice.page.stt.modelDownloading": "Descargando modelo...",
|
||||
"settings.voice.page.stt.modelDownloadingProgress": "Descargando modelo... {percent}%",
|
||||
"settings.voice.page.stt.modelNotInstalled": "Modelo no descargado",
|
||||
"settings.voice.page.stt.modelDownload": "Descargar",
|
||||
"settings.voice.page.stt.modelDelete": "Eliminar modelo",
|
||||
"settings.voice.page.stt.modelRetry": "Reintentar",
|
||||
"settings.voice.page.provider.wasm": "Local",
|
||||
"settings.voice.page.stt.wasmModel": "Modelo Whisper",
|
||||
"settings.voice.page.stt.wasmLoaded": "Modelo cargado",
|
||||
|
||||
@@ -1245,6 +1245,18 @@ export const dict: Record<I18nKey, string> = {
|
||||
'diffView.reviewDialog.actions.starting': 'Iniciando...',
|
||||
'diffView.reviewDialog.toast.noSessionDirectory': 'El directorio de la sesión no está disponible',
|
||||
'diffView.reviewDialog.toast.startFailed': 'No se pudo iniciar el flujo de revisión',
|
||||
'chat.dictation.start': 'Iniciar dictado',
|
||||
'chat.dictation.overlayAria': 'Dictado',
|
||||
'chat.dictation.downloadingModel': 'Descargando el modelo de voz...',
|
||||
'chat.dictation.downloadingModelProgress': 'Descargando el modelo de voz... {percent}%',
|
||||
'chat.dictation.listening': 'Escuchando...',
|
||||
'chat.dictation.processing': 'Transcribiendo...',
|
||||
'chat.dictation.failed': 'La transcripción falló',
|
||||
'chat.dictation.cancel': 'Descartar dictado',
|
||||
'chat.dictation.insert': 'Insertar transcripción',
|
||||
'chat.dictation.insertAndSend': 'Insertar y enviar',
|
||||
'chat.dictation.retry': 'Reintentar transcripción',
|
||||
'chat.dictation.discard': 'Descartar grabación',
|
||||
'chat.history.loadOlder': 'Cargar mensajes anteriores',
|
||||
'chat.autoReview.title': 'El ciclo de revisión de código está en curso',
|
||||
'chat.autoReview.status.waitingForReviewer': 'Esperando al revisor',
|
||||
|
||||
@@ -1468,16 +1468,33 @@ export const settingsDict = {
|
||||
'settings.notifications.page.toast.backgroundDisabled': 'Notifications en arrière-plan désactivées',
|
||||
'settings.notifications.page.testNotification.title': 'Avis de test',
|
||||
'settings.notifications.page.testNotification.body': 'Il s\'agit d\'une notification de test de OpenChamber.',
|
||||
'settings.voice.page.section.voiceSetup': 'Configuration vocale',
|
||||
'settings.voice.page.section.speechRecognition': 'Reconnaissance vocale',
|
||||
'settings.voice.page.field.enableVoiceInput': 'Activer la saisie vocale',
|
||||
'settings.voice.page.field.enableVoiceInputAria': 'Activer la saisie vocale (dictée)',
|
||||
'settings.voice.page.section.playbackAndSummary': 'Lecture',
|
||||
'settings.voice.page.field.enableVoiceModeAria': 'Activer le mode vocal',
|
||||
'settings.voice.page.field.enableVoiceMode': 'Activer le mode vocal',
|
||||
'settings.voice.page.field.provider': 'Fournisseur',
|
||||
'settings.voice.page.provider.browser': 'Navigateur',
|
||||
'settings.voice.page.provider.custom': 'Personnalisé',
|
||||
'settings.voice.page.provider.say': 'Dire',
|
||||
'settings.voice.page.provider.server': 'Serveur',
|
||||
'settings.voice.page.provider.local': 'Local',
|
||||
'settings.voice.page.tooltip.sttLocal': 'Transcription locale sur le serveur OpenChamber. Les modèles se téléchargent automatiquement ; aucune clé d\'API requise.',
|
||||
'settings.voice.page.tooltip.localTts': 'Synthèse locale sur le serveur OpenChamber (Kokoro, anglais). Le modèle se télécharge automatiquement ; aucune clé d’API requise.',
|
||||
'settings.voice.page.stt.model.parakeetV2': 'Parakeet v2 (anglais)',
|
||||
'settings.voice.page.stt.model.parakeetV3': 'Parakeet v3 (25 langues européennes)',
|
||||
'settings.voice.page.stt.model.whisperBase': 'Whisper base (multilingue)',
|
||||
'settings.voice.page.stt.model.whisperTiny': 'Whisper tiny (multilingue)',
|
||||
'settings.voice.page.stt.badge.bestForEnglish': 'Idéal pour l’anglais',
|
||||
'settings.voice.page.stt.badge.bestForMultilingual': 'Idéal multilingue',
|
||||
'settings.voice.page.stt.meta.accuracy': 'Précision',
|
||||
'settings.voice.page.stt.meta.speed': 'Vitesse',
|
||||
'settings.voice.page.stt.modelInstalled': 'Modèle installé',
|
||||
'settings.voice.page.stt.modelDownloading': 'Téléchargement du modèle...',
|
||||
'settings.voice.page.stt.modelDownloadingProgress': 'Téléchargement du modèle... {percent}%',
|
||||
'settings.voice.page.stt.modelNotInstalled': 'Modèle non téléchargé',
|
||||
'settings.voice.page.stt.modelDownload': 'Télécharger',
|
||||
'settings.voice.page.stt.modelDelete': 'Supprimer le modèle',
|
||||
'settings.voice.page.stt.modelRetry': 'Réessayer',
|
||||
'settings.voice.page.provider.wasm': 'Local',
|
||||
'settings.voice.page.stt.wasmModel': 'Modèle Whisper',
|
||||
'settings.voice.page.stt.wasmLoaded': 'Modèle chargé, prêt',
|
||||
|
||||
@@ -1669,6 +1669,18 @@ export const dict = {
|
||||
'chat.chatInput.placeholder.chat': '@ pour les fichiers/agents ; / pour les commandes et les skills ; ! pour shell ; # pour les extraits',
|
||||
'chat.chatInput.placeholder.chatCompact': 'Utiliser @ / ! # pour les aides',
|
||||
'chat.chatInput.placeholder.selectSession': 'Sélectionnez ou créez une session pour commencer à discuter',
|
||||
'chat.dictation.start': 'Démarrer la dictée',
|
||||
'chat.dictation.overlayAria': 'Dictée',
|
||||
'chat.dictation.downloadingModel': 'Téléchargement du modèle vocal...',
|
||||
'chat.dictation.downloadingModelProgress': 'Téléchargement du modèle vocal... {percent}%',
|
||||
'chat.dictation.listening': 'Écoute...',
|
||||
'chat.dictation.processing': 'Transcription...',
|
||||
'chat.dictation.failed': 'Échec de la transcription',
|
||||
'chat.dictation.cancel': 'Abandonner la dictée',
|
||||
'chat.dictation.insert': 'Insérer la transcription',
|
||||
'chat.dictation.insertAndSend': 'Insérer et envoyer',
|
||||
'chat.dictation.retry': 'Réessayer la transcription',
|
||||
'chat.dictation.discard': 'Abandonner l\'enregistrement',
|
||||
'chat.snippetAutocomplete.action.addNew': '+ Ajouter un nouvel extrait',
|
||||
'chat.snippetAutocomplete.empty': 'Aucun extrait trouvé',
|
||||
'chat.snippetAutocomplete.footer': '↑↓ naviguer • Entrer sélectionner • Esc fermer',
|
||||
|
||||
@@ -1518,16 +1518,33 @@ export const settingsDict = {
|
||||
'settings.notifications.page.toast.backgroundDisabled': 'バックグラウンド通知を無効化しました',
|
||||
'settings.notifications.page.testNotification.title': 'テスト通知',
|
||||
'settings.notifications.page.testNotification.body': 'これは OpenChamber からのテスト通知です。',
|
||||
'settings.voice.page.section.voiceSetup': '音声設定',
|
||||
'settings.voice.page.section.speechRecognition': '音声認識',
|
||||
'settings.voice.page.field.enableVoiceInput': '音声入力を有効にする',
|
||||
'settings.voice.page.field.enableVoiceInputAria': '音声入力(ディクテーション)を有効にする',
|
||||
'settings.voice.page.section.playbackAndSummary': '再生',
|
||||
'settings.voice.page.field.enableVoiceModeAria': '音声モードを有効化',
|
||||
'settings.voice.page.field.enableVoiceMode': '音声モードを有効化',
|
||||
'settings.voice.page.field.provider': 'プロバイダー',
|
||||
'settings.voice.page.provider.browser': 'ブラウザ',
|
||||
'settings.voice.page.provider.custom': 'カスタム',
|
||||
'settings.voice.page.provider.say': 'Say',
|
||||
'settings.voice.page.provider.server': 'サーバー',
|
||||
'settings.voice.page.provider.local': 'ローカル',
|
||||
'settings.voice.page.tooltip.sttLocal': 'OpenChamber サーバー上でローカルに文字起こしします。モデルは自動でダウンロードされ、API キーは不要です。',
|
||||
'settings.voice.page.tooltip.localTts': 'OpenChamber サーバー上でローカルに音声合成します(Kokoro、英語)。モデルは自動でダウンロードされ、API キーは不要です。',
|
||||
'settings.voice.page.stt.model.parakeetV2': 'Parakeet v2(英語)',
|
||||
'settings.voice.page.stt.model.parakeetV3': 'Parakeet v3(ヨーロッパ25言語)',
|
||||
'settings.voice.page.stt.model.whisperBase': 'Whisper base(多言語)',
|
||||
'settings.voice.page.stt.model.whisperTiny': 'Whisper tiny(多言語)',
|
||||
'settings.voice.page.stt.badge.bestForEnglish': '英語に最適',
|
||||
'settings.voice.page.stt.badge.bestForMultilingual': '多言語に最適',
|
||||
'settings.voice.page.stt.meta.accuracy': '精度',
|
||||
'settings.voice.page.stt.meta.speed': '速度',
|
||||
'settings.voice.page.stt.modelInstalled': 'モデルはインストール済み',
|
||||
'settings.voice.page.stt.modelDownloading': 'モデルをダウンロード中...',
|
||||
'settings.voice.page.stt.modelDownloadingProgress': 'モデルをダウンロード中... {percent}%',
|
||||
'settings.voice.page.stt.modelNotInstalled': 'モデル未ダウンロード',
|
||||
'settings.voice.page.stt.modelDownload': 'ダウンロード',
|
||||
'settings.voice.page.stt.modelDelete': 'モデルを削除',
|
||||
'settings.voice.page.stt.modelRetry': '再試行',
|
||||
'settings.voice.page.provider.wasm': 'ローカル',
|
||||
'settings.voice.page.stt.wasmModel': 'Whisper モデル',
|
||||
'settings.voice.page.stt.wasmLoaded': 'モデル読み込み完了',
|
||||
|
||||
@@ -1869,6 +1869,18 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.chatInput.placeholder.chat': '@でファイル/エージェント、/でコマンド/スキル、!でシェル、#でスニペット',
|
||||
'chat.chatInput.placeholder.chatCompact': '@ / ! # でヘルパーを使用',
|
||||
'chat.chatInput.placeholder.selectSession': 'セッションを選択または作成してチャットを開始',
|
||||
'chat.dictation.start': '音声入力を開始',
|
||||
'chat.dictation.overlayAria': '音声入力',
|
||||
'chat.dictation.downloadingModel': '音声モデルをダウンロード中...',
|
||||
'chat.dictation.downloadingModelProgress': '音声モデルをダウンロード中... {percent}%',
|
||||
'chat.dictation.listening': '聞き取り中...',
|
||||
'chat.dictation.processing': '文字起こし中...',
|
||||
'chat.dictation.failed': '文字起こしに失敗しました',
|
||||
'chat.dictation.cancel': '音声入力を破棄',
|
||||
'chat.dictation.insert': 'テキストを挿入',
|
||||
'chat.dictation.insertAndSend': '挿入して送信',
|
||||
'chat.dictation.retry': '文字起こしを再試行',
|
||||
'chat.dictation.discard': '録音を破棄',
|
||||
'chat.snippetAutocomplete.action.addNew': '+ 新しいスニペットを追加',
|
||||
'chat.snippetAutocomplete.empty': 'スニペットが見つかりません',
|
||||
'chat.snippetAutocomplete.footer': '↑↓ 移動 • Enter 選択 • Esc 閉じる',
|
||||
|
||||
@@ -1485,16 +1485,33 @@ export const settingsDict = {
|
||||
'settings.notifications.page.toast.backgroundDisabled': '백그라운드 알림이 비활성화되었습니다',
|
||||
'settings.notifications.page.testNotification.title': '테스트 알림',
|
||||
'settings.notifications.page.testNotification.body': 'OpenChamber의 테스트 알림입니다.',
|
||||
'settings.voice.page.section.voiceSetup': '음성',
|
||||
'settings.voice.page.section.speechRecognition': '음성 인식',
|
||||
'settings.voice.page.field.enableVoiceInput': '음성 입력 사용',
|
||||
'settings.voice.page.field.enableVoiceInputAria': '음성 입력(받아쓰기) 사용',
|
||||
'settings.voice.page.section.playbackAndSummary': '재생',
|
||||
'settings.voice.page.field.enableVoiceModeAria': '음성 모드 활성화',
|
||||
'settings.voice.page.field.enableVoiceMode': '음성 모드 활성화',
|
||||
'settings.voice.page.field.provider': '프로바이더',
|
||||
'settings.voice.page.provider.browser': '브라우저',
|
||||
'settings.voice.page.provider.custom': '사용자 정의',
|
||||
'settings.voice.page.provider.say': 'Say',
|
||||
'settings.voice.page.provider.server': '서버',
|
||||
'settings.voice.page.provider.local': '로컬',
|
||||
'settings.voice.page.tooltip.sttLocal': 'OpenChamber 서버에서 로컬로 변환합니다. 모델은 자동으로 다운로드되며 API 키가 필요 없습니다.',
|
||||
'settings.voice.page.tooltip.localTts': 'OpenChamber 서버에서 로컬로 음성을 합성합니다(Kokoro, 영어). 모델은 자동으로 다운로드되며 API 키가 필요 없습니다.',
|
||||
'settings.voice.page.stt.model.parakeetV2': 'Parakeet v2 (영어)',
|
||||
'settings.voice.page.stt.model.parakeetV3': 'Parakeet v3 (유럽 25개 언어)',
|
||||
'settings.voice.page.stt.model.whisperBase': 'Whisper base (다국어)',
|
||||
'settings.voice.page.stt.model.whisperTiny': 'Whisper tiny (다국어)',
|
||||
'settings.voice.page.stt.badge.bestForEnglish': '영어에 최적',
|
||||
'settings.voice.page.stt.badge.bestForMultilingual': '다국어에 최적',
|
||||
'settings.voice.page.stt.meta.accuracy': '정확도',
|
||||
'settings.voice.page.stt.meta.speed': '속도',
|
||||
'settings.voice.page.stt.modelInstalled': '모델 설치됨',
|
||||
'settings.voice.page.stt.modelDownloading': '모델 다운로드 중...',
|
||||
'settings.voice.page.stt.modelDownloadingProgress': '모델 다운로드 중... {percent}%',
|
||||
'settings.voice.page.stt.modelNotInstalled': '모델이 다운로드되지 않음',
|
||||
'settings.voice.page.stt.modelDownload': '다운로드',
|
||||
'settings.voice.page.stt.modelDelete': '모델 삭제',
|
||||
'settings.voice.page.stt.modelRetry': '다시 시도',
|
||||
'settings.voice.page.provider.wasm': '로컬',
|
||||
'settings.voice.page.stt.wasmModel': 'Whisper 모델',
|
||||
'settings.voice.page.stt.wasmLoaded': '모델 로드됨',
|
||||
|
||||
@@ -1873,6 +1873,18 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.chatInput.placeholder.chat': '@ 파일/에이전트; / 명령 및 스킬; ! shell; # 스니펫',
|
||||
'chat.chatInput.placeholder.chatCompact': '@ / ! # 도우미 사용',
|
||||
'chat.chatInput.placeholder.selectSession': '채팅을 시작할 세션을 선택하거나 새로 만드세요',
|
||||
'chat.dictation.start': '받아쓰기 시작',
|
||||
'chat.dictation.overlayAria': '받아쓰기',
|
||||
'chat.dictation.downloadingModel': '음성 모델 다운로드 중...',
|
||||
'chat.dictation.downloadingModelProgress': '음성 모델 다운로드 중... {percent}%',
|
||||
'chat.dictation.listening': '듣는 중...',
|
||||
'chat.dictation.processing': '변환 중...',
|
||||
'chat.dictation.failed': '변환에 실패했습니다',
|
||||
'chat.dictation.cancel': '받아쓰기 취소',
|
||||
'chat.dictation.insert': '텍스트 삽입',
|
||||
'chat.dictation.insertAndSend': '삽입 후 전송',
|
||||
'chat.dictation.retry': '변환 다시 시도',
|
||||
'chat.dictation.discard': '녹음 삭제',
|
||||
'chat.snippetAutocomplete.action.addNew': '+ 새 스니펫 추가',
|
||||
'chat.snippetAutocomplete.empty': '스니펫을 찾을 수 없음',
|
||||
'chat.snippetAutocomplete.footer': '↑↓ 이동 • Enter 선택 • Esc 닫기',
|
||||
|
||||
@@ -1743,8 +1743,6 @@ export const settingsDict = {
|
||||
'settings.voice.page.field.apiKeyHintUsingConfig': 'Użyto klucza z konfiguracji',
|
||||
'settings.voice.page.field.auto': 'Auto',
|
||||
'settings.voice.page.field.configuredAbove': 'Skonfigurowano powyżej',
|
||||
'settings.voice.page.field.enableVoiceMode': 'Włącz tryb głosowy',
|
||||
'settings.voice.page.field.enableVoiceModeAria': 'Włącz tryb głosowy',
|
||||
'settings.voice.page.field.language': 'Język',
|
||||
'settings.voice.page.field.messageReadAloudButton': 'Przycisk czytania wiadomości na głos',
|
||||
'settings.voice.page.field.messageReadAloudButtonAria': 'Przycisk czytania wiadomości na głos',
|
||||
@@ -1782,6 +1780,24 @@ export const settingsDict = {
|
||||
'settings.voice.page.provider.custom': 'Własny',
|
||||
'settings.voice.page.provider.say': 'Say',
|
||||
'settings.voice.page.provider.server': 'Serwer',
|
||||
'settings.voice.page.provider.local': 'Lokalny',
|
||||
'settings.voice.page.tooltip.sttLocal': 'Transkrypcja lokalna na serwerze OpenChamber. Modele pobierają się automatycznie; klucz API nie jest potrzebny.',
|
||||
'settings.voice.page.tooltip.localTts': 'Lokalna synteza na serwerze OpenChamber (Kokoro, angielski). Model pobiera się automatycznie; klucz API nie jest potrzebny.',
|
||||
'settings.voice.page.stt.model.parakeetV2': 'Parakeet v2 (angielski)',
|
||||
'settings.voice.page.stt.model.parakeetV3': 'Parakeet v3 (25 języków europejskich)',
|
||||
'settings.voice.page.stt.model.whisperBase': 'Whisper base (wielojęzyczny)',
|
||||
'settings.voice.page.stt.model.whisperTiny': 'Whisper tiny (wielojęzyczny)',
|
||||
'settings.voice.page.stt.badge.bestForEnglish': 'Najlepszy do angielskiego',
|
||||
'settings.voice.page.stt.badge.bestForMultilingual': 'Najlepszy wielojęzyczny',
|
||||
'settings.voice.page.stt.meta.accuracy': 'Dokładność',
|
||||
'settings.voice.page.stt.meta.speed': 'Szybkość',
|
||||
'settings.voice.page.stt.modelInstalled': 'Model zainstalowany',
|
||||
'settings.voice.page.stt.modelDownloading': 'Pobieranie modelu...',
|
||||
'settings.voice.page.stt.modelDownloadingProgress': 'Pobieranie modelu... {percent}%',
|
||||
'settings.voice.page.stt.modelNotInstalled': 'Model niepobrany',
|
||||
'settings.voice.page.stt.modelDownload': 'Pobierz',
|
||||
'settings.voice.page.stt.modelDelete': 'Usuń model',
|
||||
'settings.voice.page.stt.modelRetry': 'Ponów',
|
||||
'settings.voice.page.provider.wasm': 'Lokalny',
|
||||
'settings.voice.page.stt.wasmModel': 'Model Whisper',
|
||||
'settings.voice.page.stt.wasmLoaded': 'Model załadowany',
|
||||
@@ -1792,7 +1808,8 @@ export const settingsDict = {
|
||||
'settings.voice.page.stt.wasmRetry': 'Spróbuj ponownie',
|
||||
'settings.voice.page.section.playbackAndSummary': 'Odtwarzanie',
|
||||
'settings.voice.page.section.speechRecognition': 'Rozpoznawanie mowy',
|
||||
'settings.voice.page.section.voiceSetup': 'Konfiguracja głosu',
|
||||
'settings.voice.page.field.enableVoiceInput': 'Włącz wprowadzanie głosowe',
|
||||
'settings.voice.page.field.enableVoiceInputAria': 'Włącz wprowadzanie głosowe (dyktowanie)',
|
||||
'settings.voice.page.tooltip.browser': 'Darmowe, offline, ograniczone wsparcie mobilne.',
|
||||
'settings.voice.page.tooltip.custom': 'Serwer zgodny z OpenAI (na przykład Kokoro).',
|
||||
'settings.voice.page.tooltip.openai': 'Wysoka jakość, gotowe na urządzenia mobilne, wymaga klucza API.',
|
||||
|
||||
@@ -1091,6 +1091,18 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.chatInput.placeholder.chatCompact': 'Użyj @ / ! # dla pomocników',
|
||||
'chat.chatInput.placeholder.selectSession': 'Wybierz lub utwórz sesję, aby zacząć czatować',
|
||||
'chat.chatInput.placeholder.shell': 'Wpisz polecenie powłoki...',
|
||||
'chat.dictation.start': 'Rozpocznij dyktowanie',
|
||||
'chat.dictation.overlayAria': 'Dyktowanie',
|
||||
'chat.dictation.downloadingModel': 'Pobieranie modelu mowy...',
|
||||
'chat.dictation.downloadingModelProgress': 'Pobieranie modelu mowy... {percent}%',
|
||||
'chat.dictation.listening': 'Słucham...',
|
||||
'chat.dictation.processing': 'Transkrybowanie...',
|
||||
'chat.dictation.failed': 'Transkrypcja nie powiodła się',
|
||||
'chat.dictation.cancel': 'Odrzuć dyktowanie',
|
||||
'chat.dictation.insert': 'Wstaw transkrypcję',
|
||||
'chat.dictation.insertAndSend': 'Wstaw i wyślij',
|
||||
'chat.dictation.retry': 'Ponów transkrypcję',
|
||||
'chat.dictation.discard': 'Odrzuć nagranie',
|
||||
'chat.snippetAutocomplete.action.addNew': '+ Dodaj nowy fragment',
|
||||
'chat.snippetAutocomplete.empty': 'Nie znaleziono fragmentów',
|
||||
'chat.snippetAutocomplete.footer': '↑↓ nawigacja • Enter wybierz • Esc zamknij',
|
||||
|
||||
@@ -1485,16 +1485,33 @@ export const settingsDict = {
|
||||
"settings.notifications.page.toast.backgroundDisabled": "Notificações em segundo plano desabilitadas",
|
||||
"settings.notifications.page.testNotification.title": "Notificação de teste",
|
||||
"settings.notifications.page.testNotification.body": "Esta é uma notificação de teste do OpenChamber.",
|
||||
"settings.voice.page.section.voiceSetup": "Configurações de voz",
|
||||
"settings.voice.page.section.speechRecognition": "Reconhecimento de voz",
|
||||
"settings.voice.page.field.enableVoiceInput": "Ativar entrada por voz",
|
||||
"settings.voice.page.field.enableVoiceInputAria": "Ativar entrada por voz (ditado)",
|
||||
"settings.voice.page.section.playbackAndSummary": "Reprodução",
|
||||
"settings.voice.page.field.enableVoiceModeAria": "Ativar modo de voz",
|
||||
"settings.voice.page.field.enableVoiceMode": "Ativar modo de voz",
|
||||
"settings.voice.page.field.provider": "Provedor",
|
||||
"settings.voice.page.provider.browser": "Navegador",
|
||||
"settings.voice.page.provider.custom": "Personalizado",
|
||||
"settings.voice.page.provider.say": "Falar",
|
||||
"settings.voice.page.provider.server": "Servidor",
|
||||
"settings.voice.page.provider.local": "Local",
|
||||
"settings.voice.page.tooltip.sttLocal": "Transcrição local no servidor do OpenChamber. Os modelos são baixados automaticamente; não é necessária chave de API.",
|
||||
"settings.voice.page.tooltip.localTts": "Síntese local no servidor do OpenChamber (Kokoro, inglês). O modelo é baixado automaticamente; não é necessária chave de API.",
|
||||
"settings.voice.page.stt.model.parakeetV2": "Parakeet v2 (inglês)",
|
||||
"settings.voice.page.stt.model.parakeetV3": "Parakeet v3 (25 idiomas europeus)",
|
||||
"settings.voice.page.stt.model.whisperBase": "Whisper base (multilíngue)",
|
||||
"settings.voice.page.stt.model.whisperTiny": "Whisper tiny (multilíngue)",
|
||||
"settings.voice.page.stt.badge.bestForEnglish": "Melhor para inglês",
|
||||
"settings.voice.page.stt.badge.bestForMultilingual": "Melhor multilíngue",
|
||||
"settings.voice.page.stt.meta.accuracy": "Precisão",
|
||||
"settings.voice.page.stt.meta.speed": "Velocidade",
|
||||
"settings.voice.page.stt.modelInstalled": "Modelo instalado",
|
||||
"settings.voice.page.stt.modelDownloading": "Baixando modelo...",
|
||||
"settings.voice.page.stt.modelDownloadingProgress": "Baixando modelo... {percent}%",
|
||||
"settings.voice.page.stt.modelNotInstalled": "Modelo não baixado",
|
||||
"settings.voice.page.stt.modelDownload": "Baixar",
|
||||
"settings.voice.page.stt.modelDelete": "Excluir modelo",
|
||||
"settings.voice.page.stt.modelRetry": "Tentar novamente",
|
||||
"settings.voice.page.provider.wasm": "Local",
|
||||
"settings.voice.page.stt.wasmModel": "Modelo Whisper",
|
||||
"settings.voice.page.stt.wasmLoaded": "Modelo carregado",
|
||||
|
||||
@@ -1245,6 +1245,18 @@ export const dict: Record<I18nKey, string> = {
|
||||
'diffView.reviewDialog.actions.starting': 'Iniciando...',
|
||||
'diffView.reviewDialog.toast.noSessionDirectory': 'O diretório da sessão está indisponível',
|
||||
'diffView.reviewDialog.toast.startFailed': 'Falha ao iniciar o fluxo de revisão',
|
||||
'chat.dictation.start': 'Iniciar ditado',
|
||||
'chat.dictation.overlayAria': 'Ditado',
|
||||
'chat.dictation.downloadingModel': 'Baixando o modelo de fala...',
|
||||
'chat.dictation.downloadingModelProgress': 'Baixando o modelo de fala... {percent}%',
|
||||
'chat.dictation.listening': 'Ouvindo...',
|
||||
'chat.dictation.processing': 'Transcrevendo...',
|
||||
'chat.dictation.failed': 'Falha na transcrição',
|
||||
'chat.dictation.cancel': 'Descartar ditado',
|
||||
'chat.dictation.insert': 'Inserir transcrição',
|
||||
'chat.dictation.insertAndSend': 'Inserir e enviar',
|
||||
'chat.dictation.retry': 'Tentar transcrever novamente',
|
||||
'chat.dictation.discard': 'Descartar gravação',
|
||||
'chat.history.loadOlder': 'Carregar mensagens anteriores',
|
||||
'chat.autoReview.title': 'O ciclo de revisão de código está em andamento',
|
||||
'chat.autoReview.status.waitingForReviewer': 'Aguardando o revisor',
|
||||
|
||||
@@ -1485,16 +1485,33 @@ export const settingsDict = {
|
||||
"settings.notifications.page.toast.backgroundDisabled": "Фонові сповіщення вимкнено",
|
||||
"settings.notifications.page.testNotification.title": "Тестове сповіщення",
|
||||
"settings.notifications.page.testNotification.body": "Це тестове сповіщення від OpenChamber.",
|
||||
"settings.voice.page.section.voiceSetup": "Налаштування голосу",
|
||||
"settings.voice.page.section.speechRecognition": "Розпізнавання мовлення",
|
||||
"settings.voice.page.field.enableVoiceInput": "Увімкнути голосовий ввід",
|
||||
"settings.voice.page.field.enableVoiceInputAria": "Увімкнути голосовий ввід (диктування)",
|
||||
"settings.voice.page.section.playbackAndSummary": "Відтворення",
|
||||
"settings.voice.page.field.enableVoiceModeAria": "Увімкнути голосовий режим",
|
||||
"settings.voice.page.field.enableVoiceMode": "Увімкнути голосовий режим",
|
||||
"settings.voice.page.field.provider": "Провайдер",
|
||||
"settings.voice.page.provider.browser": "Браузер",
|
||||
"settings.voice.page.provider.custom": "Власний",
|
||||
"settings.voice.page.provider.say": "Say",
|
||||
"settings.voice.page.provider.server": "Сервер",
|
||||
"settings.voice.page.provider.local": "Локальний",
|
||||
"settings.voice.page.tooltip.sttLocal": "Локальна розшифровка на сервері OpenChamber. Моделі завантажуються автоматично; ключ API не потрібен.",
|
||||
"settings.voice.page.tooltip.localTts": "Локальний синтез на сервері OpenChamber (Kokoro, англійська). Модель завантажується автоматично; ключ API не потрібен.",
|
||||
"settings.voice.page.stt.model.parakeetV2": "Parakeet v2 (англійська)",
|
||||
"settings.voice.page.stt.model.parakeetV3": "Parakeet v3 (25 європейських мов)",
|
||||
"settings.voice.page.stt.model.whisperBase": "Whisper base (мультимовна)",
|
||||
"settings.voice.page.stt.model.whisperTiny": "Whisper tiny (мультимовна)",
|
||||
"settings.voice.page.stt.badge.bestForEnglish": "Найкраща для англійської",
|
||||
"settings.voice.page.stt.badge.bestForMultilingual": "Найкраща мультимовна",
|
||||
"settings.voice.page.stt.meta.accuracy": "Точність",
|
||||
"settings.voice.page.stt.meta.speed": "Швидкість",
|
||||
"settings.voice.page.stt.modelInstalled": "Модель встановлено",
|
||||
"settings.voice.page.stt.modelDownloading": "Завантаження моделі...",
|
||||
"settings.voice.page.stt.modelDownloadingProgress": "Завантаження моделі... {percent}%",
|
||||
"settings.voice.page.stt.modelNotInstalled": "Модель не завантажено",
|
||||
"settings.voice.page.stt.modelDownload": "Завантажити",
|
||||
"settings.voice.page.stt.modelDelete": "Видалити модель",
|
||||
"settings.voice.page.stt.modelRetry": "Повторити",
|
||||
"settings.voice.page.provider.wasm": "Локально",
|
||||
"settings.voice.page.stt.wasmModel": "Модель Whisper",
|
||||
"settings.voice.page.stt.wasmLoaded": "Модель завантажено",
|
||||
|
||||
@@ -1245,6 +1245,18 @@ export const dict: Record<I18nKey, string> = {
|
||||
'diffView.reviewDialog.actions.starting': 'Запуск...',
|
||||
'diffView.reviewDialog.toast.noSessionDirectory': 'Директорія сесії недоступна',
|
||||
'diffView.reviewDialog.toast.startFailed': 'Не вдалося запустити review flow',
|
||||
'chat.dictation.start': 'Почати диктування',
|
||||
'chat.dictation.overlayAria': 'Диктування',
|
||||
'chat.dictation.downloadingModel': 'Завантаження мовної моделі...',
|
||||
'chat.dictation.downloadingModelProgress': 'Завантаження мовної моделі... {percent}%',
|
||||
'chat.dictation.listening': 'Слухаю...',
|
||||
'chat.dictation.processing': 'Розшифровка...',
|
||||
'chat.dictation.failed': 'Не вдалося розшифрувати запис',
|
||||
'chat.dictation.cancel': 'Відхилити диктування',
|
||||
'chat.dictation.insert': 'Вставити текст',
|
||||
'chat.dictation.insertAndSend': 'Вставити й надіслати',
|
||||
'chat.dictation.retry': 'Повторити розшифровку',
|
||||
'chat.dictation.discard': 'Відхилити запис',
|
||||
'chat.history.loadOlder': 'Завантажити ще',
|
||||
'chat.autoReview.title': 'Цикл код-ревʼю триває',
|
||||
'chat.autoReview.status.waitingForReviewer': 'Очікуємо ревʼювера',
|
||||
|
||||
@@ -1485,16 +1485,33 @@ export const settingsDict = {
|
||||
'settings.notifications.page.toast.backgroundDisabled': '后台通知已关闭',
|
||||
'settings.notifications.page.testNotification.title': '测试通知',
|
||||
'settings.notifications.page.testNotification.body': '这是来自 OpenChamber 的测试通知。',
|
||||
'settings.voice.page.section.voiceSetup': '语音设置',
|
||||
'settings.voice.page.section.speechRecognition': '语音识别',
|
||||
'settings.voice.page.field.enableVoiceInput': '启用语音输入',
|
||||
'settings.voice.page.field.enableVoiceInputAria': '启用语音输入(听写)',
|
||||
'settings.voice.page.section.playbackAndSummary': '播放',
|
||||
'settings.voice.page.field.enableVoiceModeAria': '启用语音模式',
|
||||
'settings.voice.page.field.enableVoiceMode': '启用语音模式',
|
||||
'settings.voice.page.field.provider': '提供方',
|
||||
'settings.voice.page.provider.browser': '浏览器',
|
||||
'settings.voice.page.provider.custom': '自定义',
|
||||
'settings.voice.page.provider.say': 'Say',
|
||||
'settings.voice.page.provider.server': '服务器',
|
||||
'settings.voice.page.provider.local': '本地',
|
||||
'settings.voice.page.tooltip.sttLocal': '在 OpenChamber 服务器上本地转写。模型自动下载,无需 API 密钥。',
|
||||
'settings.voice.page.tooltip.localTts': '在 OpenChamber 服务器上本地合成语音(Kokoro,英语)。模型自动下载,无需 API 密钥。',
|
||||
'settings.voice.page.stt.model.parakeetV2': 'Parakeet v2(英语)',
|
||||
'settings.voice.page.stt.model.parakeetV3': 'Parakeet v3(25 种欧洲语言)',
|
||||
'settings.voice.page.stt.model.whisperBase': 'Whisper base(多语言)',
|
||||
'settings.voice.page.stt.model.whisperTiny': 'Whisper tiny(多语言)',
|
||||
'settings.voice.page.stt.badge.bestForEnglish': '英语最佳',
|
||||
'settings.voice.page.stt.badge.bestForMultilingual': '多语言最佳',
|
||||
'settings.voice.page.stt.meta.accuracy': '准确度',
|
||||
'settings.voice.page.stt.meta.speed': '速度',
|
||||
'settings.voice.page.stt.modelInstalled': '模型已安装',
|
||||
'settings.voice.page.stt.modelDownloading': '正在下载模型...',
|
||||
'settings.voice.page.stt.modelDownloadingProgress': '正在下载模型... {percent}%',
|
||||
'settings.voice.page.stt.modelNotInstalled': '模型未下载',
|
||||
'settings.voice.page.stt.modelDownload': '下载',
|
||||
'settings.voice.page.stt.modelDelete': '删除模型',
|
||||
'settings.voice.page.stt.modelRetry': '重试',
|
||||
'settings.voice.page.provider.wasm': '本地',
|
||||
'settings.voice.page.stt.wasmModel': 'Whisper 模型',
|
||||
'settings.voice.page.stt.wasmLoaded': '模型已加载',
|
||||
|
||||
@@ -1839,6 +1839,18 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.chatInput.placeholder.chat': '@ 用于文件/智能体;/ 用于命令和技能;! 用于 shell;# 用于代码片段',
|
||||
'chat.chatInput.placeholder.chatCompact': '使用 @ / ! # 辅助',
|
||||
'chat.chatInput.placeholder.selectSession': '选择或创建会话以开始聊天',
|
||||
'chat.dictation.start': '开始语音输入',
|
||||
'chat.dictation.overlayAria': '语音输入',
|
||||
'chat.dictation.downloadingModel': '正在下载语音模型...',
|
||||
'chat.dictation.downloadingModelProgress': '正在下载语音模型... {percent}%',
|
||||
'chat.dictation.listening': '正在聆听...',
|
||||
'chat.dictation.processing': '正在转写...',
|
||||
'chat.dictation.failed': '转写失败',
|
||||
'chat.dictation.cancel': '放弃语音输入',
|
||||
'chat.dictation.insert': '插入文本',
|
||||
'chat.dictation.insertAndSend': '插入并发送',
|
||||
'chat.dictation.retry': '重试转写',
|
||||
'chat.dictation.discard': '放弃录音',
|
||||
'chat.snippetAutocomplete.action.addNew': '+ 新建代码片段',
|
||||
'chat.snippetAutocomplete.empty': '未找到代码片段',
|
||||
'chat.snippetAutocomplete.footer': '↑↓ 导航 • Enter 选择 • Esc 关闭',
|
||||
|
||||
@@ -1401,16 +1401,33 @@
|
||||
'settings.notifications.page.toast.backgroundDisabled': '背景通知已關閉',
|
||||
'settings.notifications.page.testNotification.title': '測試通知',
|
||||
'settings.notifications.page.testNotification.body': '這是來自 OpenChamber 的測試通知。',
|
||||
'settings.voice.page.section.voiceSetup': '語音設定',
|
||||
'settings.voice.page.section.speechRecognition': '語音辨識',
|
||||
'settings.voice.page.field.enableVoiceInput': '啟用語音輸入',
|
||||
'settings.voice.page.field.enableVoiceInputAria': '啟用語音輸入(聽寫)',
|
||||
'settings.voice.page.section.playbackAndSummary': '播放',
|
||||
'settings.voice.page.field.enableVoiceModeAria': '啟用語音模式',
|
||||
'settings.voice.page.field.enableVoiceMode': '啟用語音模式',
|
||||
'settings.voice.page.field.provider': '提供方',
|
||||
'settings.voice.page.provider.browser': '瀏覽器',
|
||||
'settings.voice.page.provider.custom': '自訂',
|
||||
'settings.voice.page.provider.say': 'Say',
|
||||
'settings.voice.page.provider.server': '伺服器',
|
||||
'settings.voice.page.provider.local': '本機',
|
||||
'settings.voice.page.tooltip.sttLocal': '在 OpenChamber 伺服器上本機轉寫。模型會自動下載,無需 API 金鑰。',
|
||||
'settings.voice.page.tooltip.localTts': '在 OpenChamber 伺服器上本機合成語音(Kokoro,英文)。模型會自動下載,無需 API 金鑰。',
|
||||
'settings.voice.page.stt.model.parakeetV2': 'Parakeet v2(英文)',
|
||||
'settings.voice.page.stt.model.parakeetV3': 'Parakeet v3(25 種歐洲語言)',
|
||||
'settings.voice.page.stt.model.whisperBase': 'Whisper base(多語言)',
|
||||
'settings.voice.page.stt.model.whisperTiny': 'Whisper tiny(多語言)',
|
||||
'settings.voice.page.stt.badge.bestForEnglish': '英文最佳',
|
||||
'settings.voice.page.stt.badge.bestForMultilingual': '多語言最佳',
|
||||
'settings.voice.page.stt.meta.accuracy': '準確度',
|
||||
'settings.voice.page.stt.meta.speed': '速度',
|
||||
'settings.voice.page.stt.modelInstalled': '模型已安裝',
|
||||
'settings.voice.page.stt.modelDownloading': '正在下載模型...',
|
||||
'settings.voice.page.stt.modelDownloadingProgress': '正在下載模型... {percent}%',
|
||||
'settings.voice.page.stt.modelNotInstalled': '模型未下載',
|
||||
'settings.voice.page.stt.modelDownload': '下載',
|
||||
'settings.voice.page.stt.modelDelete': '刪除模型',
|
||||
'settings.voice.page.stt.modelRetry': '重試',
|
||||
'settings.voice.page.provider.wasm': '本機',
|
||||
'settings.voice.page.stt.wasmModel': 'Whisper 模型',
|
||||
'settings.voice.page.stt.wasmLoaded': '模型已載入',
|
||||
|
||||
@@ -1843,6 +1843,18 @@ export const dict: Record<I18nKey, string> = {
|
||||
'chat.chatInput.placeholder.chat': '@ 用於檔案/Agent;/ 用於命令;! 用於 shell;# 用於程式片段',
|
||||
'chat.chatInput.placeholder.chatCompact': '使用 @ / ! # 輔助',
|
||||
'chat.chatInput.placeholder.selectSession': '選擇或建立會話以開始聊天',
|
||||
'chat.dictation.start': '開始語音輸入',
|
||||
'chat.dictation.overlayAria': '語音輸入',
|
||||
'chat.dictation.downloadingModel': '正在下載語音模型...',
|
||||
'chat.dictation.downloadingModelProgress': '正在下載語音模型... {percent}%',
|
||||
'chat.dictation.listening': '正在聆聽...',
|
||||
'chat.dictation.processing': '正在轉寫...',
|
||||
'chat.dictation.failed': '轉寫失敗',
|
||||
'chat.dictation.cancel': '放棄語音輸入',
|
||||
'chat.dictation.insert': '插入文字',
|
||||
'chat.dictation.insertAndSend': '插入並傳送',
|
||||
'chat.dictation.retry': '重試轉寫',
|
||||
'chat.dictation.discard': '放棄錄音',
|
||||
'chat.snippetAutocomplete.action.addNew': '+ 新建程式片段',
|
||||
'chat.snippetAutocomplete.empty': '未找到程式片段',
|
||||
'chat.snippetAutocomplete.footer': '↑↓ 導航 • Enter 選擇 • Esc 關閉',
|
||||
|
||||
Reference in New Issue
Block a user