fix(providers): complete OAuth logins that finish in the browser

OpenCode's authorize response reports how the client must finish: `code`
expects a pasted code, while `auto` requires the client to call
oauth/callback immediately and hold it open — upstream blocks in there
polling for the device code or waiting on its loopback redirect, and only
that call persists the credential. Every auth plugin OpenCode ships uses
`auto`; none use `code`.

The page implemented only `code`. It opened the browser, showed a paste
field no provider can fill, and never called back, so a successful sign-in
stored nothing and the app sat unchanged. Authorization now drives the UI:
`auto` chains straight into the callback behind a waiting state with a
cancel, and the paste field appears only when a provider actually asks
for a code.

Two smaller failures shared that surface. Prompts were never collected,
which put GitHub Copilot Enterprise out of reach entirely, so a method
that declares them now asks first and passes the answers to authorize.
Device codes are also recovered from the instructions text, where they
actually live — the old code read fields the API does not return, so the
copy button never appeared.

The callback is exempt from the ordinary proxy deadline and gets a
15-minute budget, bounded by the shortest upstream expiry we know of.
A human sign-in with 2FA does not fit in four minutes, and expiring it
turned a completed login into a 504.
This commit is contained in:
Bohdan Triapitsyn
2026-08-04 19:14:58 +03:00
parent 8c37061886
commit 687681c83b
19 changed files with 1239 additions and 290 deletions
@@ -1321,6 +1321,17 @@ export const settingsDict = {
'settings.providers.page.auth.apiKeyPlaceholder': 'sk-...',
'settings.providers.page.auth.oauthMethodFallback': 'OAuth-Methode {index}',
'settings.providers.page.auth.pasteAuthorizationCodePlaceholder': 'Autorisierungscode einfügen',
'settings.providers.page.auth.oauth.starting': 'Autorisierung wird gestartet …',
'settings.providers.page.auth.oauth.waiting': 'Warten auf Autorisierung …',
'settings.providers.page.auth.oauth.waitingHint': 'Schließen Sie die Anmeldung im Browser ab. Lassen Sie diese Seite geöffnet die Verbindung wird von selbst hergestellt.',
'settings.providers.page.auth.oauth.codeHint': 'Kopieren Sie den Autorisierungscode aus dem Browser und fügen Sie ihn hier ein.',
'settings.providers.page.auth.oauth.deviceCodeLabel': 'Gerätecode',
'settings.providers.page.auth.oauth.linkLabel': 'Autorisierungslink',
'settings.providers.page.auth.oauth.promptRequired': 'Füllen Sie „{field}“ aus, um fortzufahren',
'settings.providers.page.auth.oauth.error.sessionExpired': 'Die Autorisierungsanfrage ist abgelaufen. Verbinden Sie erneut, um sie neu zu starten.',
'settings.providers.page.auth.oauth.error.codeRequired': 'Dieser Anbieter benötigt den Autorisierungscode aus Ihrem Browser.',
'settings.providers.page.auth.oauth.error.declined': 'Die Autorisierung wurde abgelehnt oder nicht abgeschlossen.',
'settings.providers.page.auth.oauth.error.invalidInput': 'Die eingegebenen Angaben wurden abgelehnt.',
'settings.providers.page.auth.connected': 'Verbunden',
'settings.providers.page.auth.incomplete': 'Anmeldedaten fehlen',
'settings.providers.page.auth.incompleteHint': '· Fügen Sie einen API-Schlüssel oder {env:VAR} hinzu, bevor Sie diesen Anbieter im Chat verwenden',
@@ -1351,6 +1362,9 @@ export const settingsDict = {
'settings.providers.page.actions.open': 'Öffnen',
'settings.providers.page.actions.copy': 'Kopieren',
'settings.providers.page.actions.complete': 'Vervollständigen',
'settings.providers.page.actions.continue': 'Weiter',
'settings.providers.page.actions.cancel': 'Abbrechen',
'settings.providers.page.actions.tryAgain': 'Wiederholen',
'settings.providers.page.actions.hide': 'Ausblenden',
'settings.providers.page.actions.reconnect': 'Erneut verbinden',
'settings.providers.page.actions.edit': 'Bearbeiten',
@@ -1365,7 +1379,6 @@ export const settingsDict = {
'settings.providers.page.toast.apiKeySaved': 'API-Schlüssel gespeichert',
'settings.providers.page.toast.oauthStartFailed': 'Fehler beim Starten des OAuth-Flows',
'settings.providers.page.toast.oauthDetailsMissing': 'Keine OAuth-Details zurückgegeben',
'settings.providers.page.toast.completeOAuthInBrowser': 'Schließen Sie den OAuth-Flow in Ihrem Browser ab',
'settings.providers.page.toast.oauthCompleteFailed': 'Fehler beim Abschließen des OAuth-Flows',
'settings.providers.page.toast.oauthCompleted': 'OAuth-Verbindung abgeschlossen',
'settings.providers.page.toast.oauthLinkCopied': 'OAuth-Link kopiert',
@@ -1386,6 +1386,17 @@ export const settingsDict = {
'settings.providers.page.auth.apiKeyPlaceholder': 'sk-...',
'settings.providers.page.auth.oauthMethodFallback': 'OAuth method {index}',
'settings.providers.page.auth.pasteAuthorizationCodePlaceholder': 'Paste authorization code',
'settings.providers.page.auth.oauth.starting': 'Starting authorization…',
'settings.providers.page.auth.oauth.waiting': 'Waiting for authorization…',
'settings.providers.page.auth.oauth.waitingHint': 'Finish signing in in your browser. Keep this page open — the connection completes on its own.',
'settings.providers.page.auth.oauth.codeHint': 'Copy the authorization code from your browser and paste it here.',
'settings.providers.page.auth.oauth.deviceCodeLabel': 'Device code',
'settings.providers.page.auth.oauth.linkLabel': 'Authorization link',
'settings.providers.page.auth.oauth.promptRequired': 'Fill in “{field}” to continue',
'settings.providers.page.auth.oauth.error.sessionExpired': 'The authorization request expired. Connect again to restart it.',
'settings.providers.page.auth.oauth.error.codeRequired': 'This provider needs the authorization code from your browser.',
'settings.providers.page.auth.oauth.error.declined': 'Authorization was declined or did not complete.',
'settings.providers.page.auth.oauth.error.invalidInput': 'The details you entered were rejected.',
'settings.providers.page.auth.connected': 'Connected',
'settings.providers.page.auth.incomplete': 'Credentials missing',
'settings.providers.page.auth.incompleteHint': '· Add an API key or {env:VAR} before using this provider in chat',
@@ -1416,6 +1427,9 @@ export const settingsDict = {
'settings.providers.page.actions.open': 'Open',
'settings.providers.page.actions.copy': 'Copy',
'settings.providers.page.actions.complete': 'Complete',
'settings.providers.page.actions.continue': 'Continue',
'settings.providers.page.actions.cancel': 'Cancel',
'settings.providers.page.actions.tryAgain': 'Try again',
'settings.providers.page.actions.hide': 'Hide',
'settings.providers.page.actions.reconnect': 'Reconnect',
'settings.providers.page.actions.edit': 'Edit',
@@ -1430,7 +1444,6 @@ export const settingsDict = {
'settings.providers.page.toast.apiKeySaved': 'API key saved',
'settings.providers.page.toast.oauthStartFailed': 'Failed to start OAuth flow',
'settings.providers.page.toast.oauthDetailsMissing': 'No OAuth details returned',
'settings.providers.page.toast.completeOAuthInBrowser': 'Complete the OAuth flow in your browser',
'settings.providers.page.toast.oauthCompleteFailed': 'Failed to complete OAuth flow',
'settings.providers.page.toast.oauthCompleted': 'OAuth connection completed',
'settings.providers.page.toast.oauthLinkCopied': 'OAuth link copied',
@@ -1359,6 +1359,17 @@ export const settingsDict = {
"settings.providers.page.auth.apiKeyPlaceholder": "sk-...",
"settings.providers.page.auth.oauthMethodFallback": "Método OAuth {index}",
"settings.providers.page.auth.pasteAuthorizationCodePlaceholder": "Pegar código de autorización",
"settings.providers.page.auth.oauth.starting": "Iniciando la autorización…",
"settings.providers.page.auth.oauth.waiting": "Esperando la autorización…",
"settings.providers.page.auth.oauth.waitingHint": "Termina de iniciar sesión en el navegador. Mantén esta página abierta: la conexión se completará sola.",
"settings.providers.page.auth.oauth.codeHint": "Copia el código de autorización del navegador y pégalo aquí.",
"settings.providers.page.auth.oauth.deviceCodeLabel": "Código del dispositivo",
"settings.providers.page.auth.oauth.linkLabel": "Enlace de autorización",
"settings.providers.page.auth.oauth.promptRequired": "Completa «{field}» para continuar",
"settings.providers.page.auth.oauth.error.sessionExpired": "La solicitud de autorización caducó. Vuelve a conectar para reiniciarla.",
"settings.providers.page.auth.oauth.error.codeRequired": "Este proveedor necesita el código de autorización de tu navegador.",
"settings.providers.page.auth.oauth.error.declined": "La autorización se rechazó o no se completó.",
"settings.providers.page.auth.oauth.error.invalidInput": "Se rechazaron los datos introducidos.",
"settings.providers.page.auth.connected": "Conectado",
"settings.providers.page.auth.incomplete": "Faltan credenciales",
"settings.providers.page.auth.incompleteHint": "· Añade una clave API o {env:VAR} antes de usar este proveedor en el chat",
@@ -1391,6 +1402,9 @@ export const settingsDict = {
"settings.providers.page.actions.open": "Abrir",
"settings.providers.page.actions.copy": "Copiar",
"settings.providers.page.actions.complete": "Completar",
"settings.providers.page.actions.continue": "Continuar",
"settings.providers.page.actions.cancel": "Cancelar",
"settings.providers.page.actions.tryAgain": "Reintentar",
"settings.providers.page.actions.hide": "Ocultar",
"settings.providers.page.actions.reconnect": "Reconectar",
"settings.providers.page.actions.edit": "Editar",
@@ -1406,7 +1420,6 @@ export const settingsDict = {
"settings.providers.page.toast.apiKeySaved": "Clave API guardada",
"settings.providers.page.toast.oauthStartFailed": "No se pudo iniciar el flujo OAuth",
"settings.providers.page.toast.oauthDetailsMissing": "No se devolvieron detalles de OAuth",
"settings.providers.page.toast.completeOAuthInBrowser": "Completa el flujo OAuth en tu navegador",
"settings.providers.page.toast.oauthCompleteFailed": "No se pudo completar el flujo OAuth",
"settings.providers.page.toast.oauthCompleted": "Conexión OAuth completada",
"settings.providers.page.toast.oauthLinkCopied": "Enlace de OAuth copiado",
@@ -1280,6 +1280,17 @@ export const settingsDict = {
'settings.providers.page.auth.apiKeyPlaceholder': 'sk-...',
'settings.providers.page.auth.oauthMethodFallback': 'Méthode OAuth {index}',
'settings.providers.page.auth.pasteAuthorizationCodePlaceholder': 'Coller le code d\'autorisation',
'settings.providers.page.auth.oauth.starting': 'Démarrage de lautorisation…',
'settings.providers.page.auth.oauth.waiting': 'En attente de lautorisation…',
'settings.providers.page.auth.oauth.waitingHint': 'Terminez la connexion dans votre navigateur. Laissez cette page ouverte : la connexion se finalisera delle-même.',
'settings.providers.page.auth.oauth.codeHint': 'Copiez le code dautorisation depuis votre navigateur et collez-le ici.',
'settings.providers.page.auth.oauth.deviceCodeLabel': 'Code de lappareil',
'settings.providers.page.auth.oauth.linkLabel': 'Lien dautorisation',
'settings.providers.page.auth.oauth.promptRequired': 'Renseignez « {field} » pour continuer',
'settings.providers.page.auth.oauth.error.sessionExpired': 'La demande dautorisation a expiré. Reconnectez-vous pour la relancer.',
'settings.providers.page.auth.oauth.error.codeRequired': 'Ce fournisseur a besoin du code dautorisation de votre navigateur.',
'settings.providers.page.auth.oauth.error.declined': 'Lautorisation a été refusée ou na pas abouti.',
'settings.providers.page.auth.oauth.error.invalidInput': 'Les informations saisies ont été refusées.',
'settings.providers.page.auth.connected': 'Connecté',
'settings.providers.page.auth.incomplete': 'Identifiants manquants',
'settings.providers.page.auth.incompleteHint': '· Ajoutez une clé API ou {env:VAR} avant dutiliser ce fournisseur dans le chat',
@@ -1312,6 +1323,9 @@ export const settingsDict = {
'settings.providers.page.actions.open': 'Ouvrir',
'settings.providers.page.actions.copy': 'Copie',
'settings.providers.page.actions.complete': 'Complet',
'settings.providers.page.actions.continue': 'Continuer',
'settings.providers.page.actions.cancel': 'Annuler',
'settings.providers.page.actions.tryAgain': 'Réessayer',
'settings.providers.page.actions.hide': 'Cacher',
'settings.providers.page.actions.reconnect': 'Reconnecter',
'settings.providers.page.actions.edit': 'Modifier',
@@ -1327,7 +1341,6 @@ export const settingsDict = {
'settings.providers.page.toast.apiKeySaved': 'Clé API enregistrée',
'settings.providers.page.toast.oauthStartFailed': 'Échec du démarrage du flux OAuth',
'settings.providers.page.toast.oauthDetailsMissing': 'Aucun détail OAuth renvoyé',
'settings.providers.page.toast.completeOAuthInBrowser': 'Complétez le flux OAuth dans votre navigateur',
'settings.providers.page.toast.oauthCompleteFailed': 'Échec de la réalisation du flux OAuth',
'settings.providers.page.toast.oauthCompleted': 'Connexion OAuth terminée',
'settings.providers.page.toast.oauthLinkCopied': 'Lien OAuth copié',
@@ -1392,6 +1392,17 @@ export const settingsDict = {
'settings.providers.page.auth.apiKeyPlaceholder': 'sk-...',
'settings.providers.page.auth.oauthMethodFallback': 'OAuth 方法 {index}',
'settings.providers.page.auth.pasteAuthorizationCodePlaceholder': '認証コードを貼り付け',
'settings.providers.page.auth.oauth.starting': '認証を開始しています…',
'settings.providers.page.auth.oauth.waiting': '認証を待っています…',
'settings.providers.page.auth.oauth.waitingHint': 'ブラウザーでサインインを完了してください。このページは開いたままにしてください。接続は自動的に完了します。',
'settings.providers.page.auth.oauth.codeHint': 'ブラウザーから認証コードをコピーして、ここに貼り付けてください。',
'settings.providers.page.auth.oauth.deviceCodeLabel': 'デバイスコード',
'settings.providers.page.auth.oauth.linkLabel': '認証リンク',
'settings.providers.page.auth.oauth.promptRequired': '続行するには「{field}」を入力してください',
'settings.providers.page.auth.oauth.error.sessionExpired': '認証リクエストの有効期限が切れました。もう一度接続してやり直してください。',
'settings.providers.page.auth.oauth.error.codeRequired': 'このプロバイダーにはブラウザーの認証コードが必要です。',
'settings.providers.page.auth.oauth.error.declined': '認証が拒否されたか、完了しませんでした。',
'settings.providers.page.auth.oauth.error.invalidInput': '入力された内容は拒否されました。',
'settings.providers.page.auth.connected': '接続済み',
'settings.providers.page.auth.incomplete': '認証情報が不足しています',
'settings.providers.page.auth.incompleteHint': '· チャットでこのプロバイダーを使う前に API キーまたは {env:VAR} を追加してください',
@@ -1424,6 +1435,9 @@ export const settingsDict = {
'settings.providers.page.actions.open': '開く',
'settings.providers.page.actions.copy': 'コピー',
'settings.providers.page.actions.complete': '完了',
'settings.providers.page.actions.continue': '続行',
'settings.providers.page.actions.cancel': 'キャンセル',
'settings.providers.page.actions.tryAgain': '再試行',
'settings.providers.page.actions.hide': '非表示',
'settings.providers.page.actions.reconnect': '再接続',
'settings.providers.page.actions.edit': '編集',
@@ -1439,7 +1453,6 @@ export const settingsDict = {
'settings.providers.page.toast.apiKeySaved': 'API キーを保存しました',
'settings.providers.page.toast.oauthStartFailed': 'OAuth フローの開始に失敗しました',
'settings.providers.page.toast.oauthDetailsMissing': 'OAuth の詳細が返されませんでした',
'settings.providers.page.toast.completeOAuthInBrowser': 'ブラウザで OAuth フローを完了してください',
'settings.providers.page.toast.oauthCompleteFailed': 'OAuth フローの完了に失敗しました',
'settings.providers.page.toast.oauthCompleted': 'OAuth 接続が完了しました',
'settings.providers.page.toast.oauthLinkCopied': 'OAuth リンクをコピーしました',
@@ -1359,6 +1359,17 @@ export const settingsDict = {
'settings.providers.page.auth.apiKeyPlaceholder': 'sk-...',
'settings.providers.page.auth.oauthMethodFallback': 'OAuth 방식 {index}',
'settings.providers.page.auth.pasteAuthorizationCodePlaceholder': 'authorization code 붙여넣기',
'settings.providers.page.auth.oauth.starting': '인증을 시작하는 중…',
'settings.providers.page.auth.oauth.waiting': '인증을 기다리는 중…',
'settings.providers.page.auth.oauth.waitingHint': '브라우저에서 로그인을 완료하세요. 이 페이지를 열어 두면 연결이 자동으로 완료됩니다.',
'settings.providers.page.auth.oauth.codeHint': '브라우저에서 인증 코드를 복사해 여기에 붙여넣으세요.',
'settings.providers.page.auth.oauth.deviceCodeLabel': '기기 코드',
'settings.providers.page.auth.oauth.linkLabel': '인증 링크',
'settings.providers.page.auth.oauth.promptRequired': '계속하려면 “{field}”을(를) 입력하세요',
'settings.providers.page.auth.oauth.error.sessionExpired': '인증 요청이 만료되었습니다. 다시 연결해 처음부터 시작하세요.',
'settings.providers.page.auth.oauth.error.codeRequired': '이 제공자에는 브라우저의 인증 코드가 필요합니다.',
'settings.providers.page.auth.oauth.error.declined': '인증이 거부되었거나 완료되지 않았습니다.',
'settings.providers.page.auth.oauth.error.invalidInput': '입력한 정보가 거부되었습니다.',
'settings.providers.page.auth.connected': '연결됨',
'settings.providers.page.auth.incomplete': '자격 증명 없음',
'settings.providers.page.auth.incompleteHint': '· 채팅에서 이 공급자를 사용하기 전에 API 키 또는 {env:VAR}을(를) 추가하세요',
@@ -1391,6 +1402,9 @@ export const settingsDict = {
'settings.providers.page.actions.open': '열기',
'settings.providers.page.actions.copy': '복사',
'settings.providers.page.actions.complete': '완료',
'settings.providers.page.actions.continue': '계속',
'settings.providers.page.actions.cancel': '취소',
'settings.providers.page.actions.tryAgain': '다시 시도',
'settings.providers.page.actions.hide': '숨기기',
'settings.providers.page.actions.reconnect': '재연결',
'settings.providers.page.actions.edit': '편집',
@@ -1406,7 +1420,6 @@ export const settingsDict = {
'settings.providers.page.toast.apiKeySaved': 'API key가 저장되었습니다',
'settings.providers.page.toast.oauthStartFailed': 'OAuth flow를 시작하지 못했습니다',
'settings.providers.page.toast.oauthDetailsMissing': '반환된 OAuth 세부 정보가 없습니다',
'settings.providers.page.toast.completeOAuthInBrowser': '브라우저에서 OAuth flow를 완료하세요',
'settings.providers.page.toast.oauthCompleteFailed': 'OAuth flow를 완료하지 못했습니다',
'settings.providers.page.toast.oauthCompleted': 'OAuth 연결이 완료되었습니다',
'settings.providers.page.toast.oauthLinkCopied': 'OAuth 링크가 복사되었습니다',
@@ -1360,6 +1360,9 @@ export const settingsDict = {
'settings.projects.sidebar.actions.addProject': 'Dodaj projekt',
'settings.projects.sidebar.total': 'Suma: {count}',
'settings.providers.page.actions.complete': 'Zakończ',
'settings.providers.page.actions.continue': 'Kontynuuj',
'settings.providers.page.actions.cancel': 'Anuluj',
'settings.providers.page.actions.tryAgain': 'Spróbuj ponownie',
'settings.providers.page.actions.connect': 'Połącz',
'settings.providers.page.actions.copy': 'Kopiuj',
'settings.providers.page.actions.copyCode': 'Kopiuj kod',
@@ -1385,6 +1388,17 @@ export const settingsDict = {
'settings.providers.page.auth.loadingMethods': 'Ładowanie metod uwierzytelniania...',
'settings.providers.page.auth.oauthMethodFallback': 'Metoda OAuth {index}',
'settings.providers.page.auth.pasteAuthorizationCodePlaceholder': 'Wklej kod autoryzacyjny',
'settings.providers.page.auth.oauth.starting': 'Rozpoczynanie autoryzacji…',
'settings.providers.page.auth.oauth.waiting': 'Oczekiwanie na autoryzację…',
'settings.providers.page.auth.oauth.waitingHint': 'Dokończ logowanie w przeglądarce. Zostaw tę stronę otwartą — połączenie zakończy się samo.',
'settings.providers.page.auth.oauth.codeHint': 'Skopiuj kod autoryzacji z przeglądarki i wklej go tutaj.',
'settings.providers.page.auth.oauth.deviceCodeLabel': 'Kod urządzenia',
'settings.providers.page.auth.oauth.linkLabel': 'Link autoryzacyjny',
'settings.providers.page.auth.oauth.promptRequired': 'Wypełnij pole „{field}”, aby kontynuować',
'settings.providers.page.auth.oauth.error.sessionExpired': 'Żądanie autoryzacji wygasło. Połącz ponownie, aby zacząć od nowa.',
'settings.providers.page.auth.oauth.error.codeRequired': 'Ten dostawca wymaga kodu autoryzacji z przeglądarki.',
'settings.providers.page.auth.oauth.error.declined': 'Autoryzacja została odrzucona lub nie została ukończona.',
'settings.providers.page.auth.oauth.error.invalidInput': 'Wprowadzone dane zostały odrzucone.',
'settings.providers.page.auth.title': 'Uwierzytelnianie',
'settings.providers.page.auth.useReconnectHint': '· Użyj Połącz ponownie, aby zaktualizować dane logowania',
'settings.providers.page.custom.optionLabel': 'Inny / Niestandardowy',
@@ -1474,7 +1488,6 @@ export const settingsDict = {
'settings.providers.page.toast.apiKeySaveFailed': 'Nie udało się zapisać klucza API',
'settings.providers.page.toast.apiKeySaved': 'Klucz API został zapisany',
'settings.providers.page.toast.authMethodsLoadFailed': 'Nie udało się załadować metod uwierzytelniania dostawcy',
'settings.providers.page.toast.completeOAuthInBrowser': 'Dokończ proces OAuth w przeglądarce',
'settings.providers.page.toast.deviceCodeCopied': 'Kod urządzenia został skopiowany',
'settings.providers.page.toast.deviceCodeCopyFailed': 'Nie udało się skopiować kodu urządzenia',
'settings.providers.page.toast.oauthCompleteFailed': 'Nie udało się dokończyć procesu OAuth',
@@ -1359,6 +1359,17 @@ export const settingsDict = {
"settings.providers.page.auth.apiKeyPlaceholder": "sk-...",
"settings.providers.page.auth.oauthMethodFallback": "Método OAuth {index}",
"settings.providers.page.auth.pasteAuthorizationCodePlaceholder": "Colar código de autorização",
"settings.providers.page.auth.oauth.starting": "Iniciando a autorização…",
"settings.providers.page.auth.oauth.waiting": "Aguardando a autorização…",
"settings.providers.page.auth.oauth.waitingHint": "Conclua o login no navegador. Mantenha esta página aberta — a conexão será concluída sozinha.",
"settings.providers.page.auth.oauth.codeHint": "Copie o código de autorização do navegador e cole aqui.",
"settings.providers.page.auth.oauth.deviceCodeLabel": "Código do dispositivo",
"settings.providers.page.auth.oauth.linkLabel": "Link de autorização",
"settings.providers.page.auth.oauth.promptRequired": "Preencha “{field}” para continuar",
"settings.providers.page.auth.oauth.error.sessionExpired": "A solicitação de autorização expirou. Conecte novamente para reiniciá-la.",
"settings.providers.page.auth.oauth.error.codeRequired": "Este provedor precisa do código de autorização do seu navegador.",
"settings.providers.page.auth.oauth.error.declined": "A autorização foi recusada ou não foi concluída.",
"settings.providers.page.auth.oauth.error.invalidInput": "Os dados informados foram recusados.",
"settings.providers.page.auth.connected": "Conectado",
"settings.providers.page.auth.incomplete": "Credenciais ausentes",
"settings.providers.page.auth.incompleteHint": "· Adicione uma chave de API ou {env:VAR} antes de usar este provedor no chat",
@@ -1391,6 +1402,9 @@ export const settingsDict = {
"settings.providers.page.actions.open": "Abrir",
"settings.providers.page.actions.copy": "Copiar",
"settings.providers.page.actions.complete": "Completar",
"settings.providers.page.actions.continue": "Continuar",
"settings.providers.page.actions.cancel": "Cancelar",
"settings.providers.page.actions.tryAgain": "Tentar novamente",
"settings.providers.page.actions.hide": "Ocultar",
"settings.providers.page.actions.reconnect": "Reconectar",
"settings.providers.page.actions.edit": "Editar",
@@ -1406,7 +1420,6 @@ export const settingsDict = {
"settings.providers.page.toast.apiKeySaved": "Chave API salva",
"settings.providers.page.toast.oauthStartFailed": "Não foi possível iniciar o fluxo OAuth",
"settings.providers.page.toast.oauthDetailsMissing": "Não se devolvieron detalhes de OAuth",
"settings.providers.page.toast.completeOAuthInBrowser": "Complete o fluxo OAuth no navegador",
"settings.providers.page.toast.oauthCompleteFailed": "Não foi possível concluir o fluxo OAuth",
"settings.providers.page.toast.oauthCompleted": "Conexão OAuth concluída",
"settings.providers.page.toast.oauthLinkCopied": "Link de OAuth copiado",
@@ -1359,6 +1359,17 @@ export const settingsDict = {
"settings.providers.page.auth.apiKeyPlaceholder": "sk-...",
"settings.providers.page.auth.oauthMethodFallback": "OAuth метод {index}",
"settings.providers.page.auth.pasteAuthorizationCodePlaceholder": "Вставити код авторизації",
"settings.providers.page.auth.oauth.starting": "Запускаємо авторизацію…",
"settings.providers.page.auth.oauth.waiting": "Очікуємо на авторизацію…",
"settings.providers.page.auth.oauth.waitingHint": "Завершіть вхід у браузері. Не закривайте цю сторінку — підключення завершиться саме.",
"settings.providers.page.auth.oauth.codeHint": "Скопіюйте код авторизації з браузера і вставте його сюди.",
"settings.providers.page.auth.oauth.deviceCodeLabel": "Код пристрою",
"settings.providers.page.auth.oauth.linkLabel": "Посилання для авторизації",
"settings.providers.page.auth.oauth.promptRequired": "Заповніть «{field}», щоб продовжити",
"settings.providers.page.auth.oauth.error.sessionExpired": "Термін дії запиту на авторизацію минув. Підключіться ще раз, щоб почати заново.",
"settings.providers.page.auth.oauth.error.codeRequired": "Цьому провайдеру потрібен код авторизації з браузера.",
"settings.providers.page.auth.oauth.error.declined": "Авторизацію відхилено або не завершено.",
"settings.providers.page.auth.oauth.error.invalidInput": "Введені дані відхилено.",
"settings.providers.page.auth.connected": "Підключено",
"settings.providers.page.auth.incomplete": "Облікові дані відсутні",
"settings.providers.page.auth.incompleteHint": "· Додайте API-ключ або {env:VAR} перед використанням цього провайдера в чаті",
@@ -1391,6 +1402,9 @@ export const settingsDict = {
"settings.providers.page.actions.open": "Відкрити",
"settings.providers.page.actions.copy": "Копіювати",
"settings.providers.page.actions.complete": "Завершити",
"settings.providers.page.actions.continue": "Продовжити",
"settings.providers.page.actions.cancel": "Скасувати",
"settings.providers.page.actions.tryAgain": "Повторити спробу",
"settings.providers.page.actions.hide": "Сховати",
"settings.providers.page.actions.reconnect": "Перепідключити",
"settings.providers.page.actions.edit": "Редагувати",
@@ -1406,7 +1420,6 @@ export const settingsDict = {
"settings.providers.page.toast.apiKeySaved": "Ключ API збережено",
"settings.providers.page.toast.oauthStartFailed": "Не вдалося запустити потік OAuth",
"settings.providers.page.toast.oauthDetailsMissing": "Деталі OAuth не повернуто",
"settings.providers.page.toast.completeOAuthInBrowser": "Завершіть процес OAuth у вашому браузері",
"settings.providers.page.toast.oauthCompleteFailed": "Не вдалося завершити потік OAuth",
"settings.providers.page.toast.oauthCompleted": "Підключення OAuth завершено",
"settings.providers.page.toast.oauthLinkCopied": "Посилання OAuth скопійовано",
@@ -1359,6 +1359,17 @@ export const settingsDict = {
'settings.providers.page.auth.apiKeyPlaceholder': 'sk-...',
'settings.providers.page.auth.oauthMethodFallback': 'OAuth 方式 {index}',
'settings.providers.page.auth.pasteAuthorizationCodePlaceholder': '粘贴授权码',
'settings.providers.page.auth.oauth.starting': '正在启动授权…',
'settings.providers.page.auth.oauth.waiting': '正在等待授权…',
'settings.providers.page.auth.oauth.waitingHint': '请在浏览器中完成登录。保持此页面打开,连接会自动完成。',
'settings.providers.page.auth.oauth.codeHint': '从浏览器复制授权码并粘贴到此处。',
'settings.providers.page.auth.oauth.deviceCodeLabel': '设备码',
'settings.providers.page.auth.oauth.linkLabel': '授权链接',
'settings.providers.page.auth.oauth.promptRequired': '请填写“{field}”后继续',
'settings.providers.page.auth.oauth.error.sessionExpired': '授权请求已过期。请重新连接以重新开始。',
'settings.providers.page.auth.oauth.error.codeRequired': '此提供方需要浏览器中的授权码。',
'settings.providers.page.auth.oauth.error.declined': '授权被拒绝或未完成。',
'settings.providers.page.auth.oauth.error.invalidInput': '输入的信息被拒绝。',
'settings.providers.page.auth.connected': '已连接',
'settings.providers.page.auth.incomplete': '缺少凭据',
'settings.providers.page.auth.incompleteHint': '· 在聊天中使用此提供商之前,请添加 API 密钥或 {env:VAR}',
@@ -1391,6 +1402,9 @@ export const settingsDict = {
'settings.providers.page.actions.open': '打开',
'settings.providers.page.actions.copy': '复制',
'settings.providers.page.actions.complete': '完成',
'settings.providers.page.actions.continue': '继续',
'settings.providers.page.actions.cancel': '取消',
'settings.providers.page.actions.tryAgain': '重试',
'settings.providers.page.actions.hide': '隐藏',
'settings.providers.page.actions.reconnect': '重新连接',
'settings.providers.page.actions.edit': '编辑',
@@ -1406,7 +1420,6 @@ export const settingsDict = {
'settings.providers.page.toast.apiKeySaved': 'API Key 已保存',
'settings.providers.page.toast.oauthStartFailed': '启动 OAuth 流程失败',
'settings.providers.page.toast.oauthDetailsMissing': '未返回 OAuth 详情',
'settings.providers.page.toast.completeOAuthInBrowser': '请在浏览器中完成 OAuth 流程',
'settings.providers.page.toast.oauthCompleteFailed': '完成 OAuth 流程失败',
'settings.providers.page.toast.oauthCompleted': 'OAuth 连接已完成',
'settings.providers.page.toast.oauthLinkCopied': 'OAuth 链接已复制',
@@ -1265,6 +1265,17 @@
'settings.providers.page.auth.apiKeyPlaceholder': 'sk-...',
'settings.providers.page.auth.oauthMethodFallback': 'OAuth 方式 {index}',
'settings.providers.page.auth.pasteAuthorizationCodePlaceholder': '貼上授權碼',
'settings.providers.page.auth.oauth.starting': '正在啟動授權…',
'settings.providers.page.auth.oauth.waiting': '正在等待授權…',
'settings.providers.page.auth.oauth.waitingHint': '請在瀏覽器中完成登入。保持此頁面開啟,連線會自動完成。',
'settings.providers.page.auth.oauth.codeHint': '從瀏覽器複製授權碼並貼上到這裡。',
'settings.providers.page.auth.oauth.deviceCodeLabel': '裝置碼',
'settings.providers.page.auth.oauth.linkLabel': '授權連結',
'settings.providers.page.auth.oauth.promptRequired': '請填寫「{field}」後繼續',
'settings.providers.page.auth.oauth.error.sessionExpired': '授權請求已過期。請重新連線以重新開始。',
'settings.providers.page.auth.oauth.error.codeRequired': '此提供者需要瀏覽器中的授權碼。',
'settings.providers.page.auth.oauth.error.declined': '授權遭拒或未完成。',
'settings.providers.page.auth.oauth.error.invalidInput': '輸入的資訊遭拒。',
'settings.providers.page.auth.connected': '已連線',
'settings.providers.page.auth.incomplete': '缺少憑證',
'settings.providers.page.auth.incompleteHint': '· 在聊天中使用此提供者之前,請新增 API 金鑰或 {env:VAR}',
@@ -1297,6 +1308,9 @@
'settings.providers.page.actions.open': '開啟',
'settings.providers.page.actions.copy': '複製',
'settings.providers.page.actions.complete': '完成',
'settings.providers.page.actions.continue': '繼續',
'settings.providers.page.actions.cancel': '取消',
'settings.providers.page.actions.tryAgain': '重試',
'settings.providers.page.actions.hide': '隱藏',
'settings.providers.page.actions.reconnect': '重新連線',
'settings.providers.page.actions.edit': '編輯',
@@ -1312,7 +1326,6 @@
'settings.providers.page.toast.apiKeySaved': 'API Key 已儲存',
'settings.providers.page.toast.oauthStartFailed': '啟動 OAuth 流程失敗',
'settings.providers.page.toast.oauthDetailsMissing': '未回傳 OAuth 詳情',
'settings.providers.page.toast.completeOAuthInBrowser': '請在瀏覽器中完成 OAuth 流程',
'settings.providers.page.toast.oauthCompleteFailed': '完成 OAuth 流程失敗',
'settings.providers.page.toast.oauthCompleted': 'OAuth 連線已完成',
'settings.providers.page.toast.oauthLinkCopied': 'OAuth 連結已複製',