From 4c50041b55f02bb8beee30ad531c2e7f1f8d1569 Mon Sep 17 00:00:00 2001
From: Peter Dave Hello <3691490+PeterDaveHello@users.noreply.github.com>
Date: Sat, 17 Oct 2026 00:46:38 +0800
Subject: [PATCH] Rework Gemini Web integration for current website protocol
Modernize the authenticated Gemini web path around the current website
protocol, keeping it text-only and fail-closed.
- Structurally parse length-framed RPC responses; validate completion,
candidate identity, continuation IDs, provider-status scope, and malformed
containers.
- Pin discovered model routing and turn indexes to continuation state;
reject cross-model or inconsistent routing before prompt submission.
- Preserve continuation uncertainty across runtime-port reconnects,
component disposal, provider switches, body-less successful submissions,
and content-bearing provider errors, so stale continuations cannot be reused.
- Keep unsafe continuation state latched across retry branches until a
successful replacement turn commits new remote state.
- Keep the last known-good local continuation on served-model mismatch,
then block further continuation until the user starts fresh.
- Use Flash as the default Gemini Web preset while retaining explicit
account-default Auto compatibility with model routing fields left unset.
- Allow the observed non-fatal 1096 status only after a valid completed
answer; keep fatal provider failures and status-only 1096 actionable.
- Use browser credentials with bounded reads, timeout, cancellation,
stale-generation guards, and no automatic retry of uncertain prompt POSTs.
- Map web-history privacy to Temporary Chat and keep route-scoped
continuation without stable account identity or selector support.
- Discover account-specific Flash-Lite, Flash, Pro, and standalone
Workspace Thinking routing instead of hard-coding the primary registry.
- Localize Gemini Web errors and drop the obsolete Bard adapter and
unused Google-cookie read.
Workspace Thinking remains a standalone web mode (mode 5), not Flash plus
Extended thinking. Model routing is pinned after the first successful turn
so registry refreshes cannot silently move an existing conversation.
Omit the ListAccounts/Gaia experiment. Live Firefox returned HTTP 400;
Chromium uses a different account-list contract. Document the account-slot
limitation (/app or /u/N) instead.
Formatting, lint, tests, production build, and browser smoke tests remain
merge gates.
Fix #723
---
src/_locales/de/main.json | 43 +
src/_locales/en/main.json | 43 +
src/_locales/es/main.json | 43 +
src/_locales/fr/main.json | 43 +
src/_locales/id/main.json | 43 +
src/_locales/it/main.json | 43 +
src/_locales/ja/main.json | 43 +
src/_locales/ko/main.json | 43 +
src/_locales/pt/main.json | 43 +
src/_locales/ru/main.json | 43 +
src/_locales/tr/main.json | 43 +
src/_locales/zh-hans/main.json | 43 +
src/_locales/zh-hant/main.json | 43 +
src/background/index.mjs | 9 +-
src/components/ConversationCard/index.jsx | 66 +-
src/components/ConversationCard/session.mjs | 75 +-
src/config/index.mjs | 2 +
src/pages/IndependentPanel/App.jsx | 5 +-
src/popup/api-mode-config-utils.mjs | 6 +
src/popup/sections/ApiModes.jsx | 225 ++++-
.../sections/api-modes-provider-utils.mjs | 18 +
src/services/apis/bard-web.mjs | 36 -
src/services/apis/gemini-web-transport.mjs | 489 +++++++++++
src/services/apis/gemini-web.mjs | 215 +++++
src/services/clients/bard/index.mjs | 137 ---
src/services/clients/gemini-web/index.mjs | 166 ++++
src/services/clients/gemini-web/protocol.mjs | 252 ++++++
src/services/init-session.mjs | 6 +-
src/services/wrappers.mjs | 43 +-
src/utils/gemini-web-preset.mjs | 105 +++
src/utils/model-name-convert.mjs | 77 +-
...nversation-card-lifecycle-loader-hooks.mjs | 7 +-
.../conversation-card-lifecycle.test.mjs | 305 +++++++
tests/unit/prettier-inspection.test.mjs | 55 ++
tests/unit/services/apis/bard-web.test.mjs | 31 -
.../services/apis/gemini-web-compat.test.mjs | 814 ++++++++++++++++++
.../apis/gemini-web-protocol.test.mjs | 343 ++++++++
.../services/apis/gemini-web-retry.test.mjs | 344 ++++++++
.../apis/gemini-web-thinking.test.mjs | 143 +++
tests/unit/services/apis/gemini-web.test.mjs | 722 ++++++++++++++++
tests/unit/services/gemini-web-i18n.test.mjs | 114 +++
tests/unit/services/init-session.test.mjs | 4 +-
.../unit/services/wrappers-register.test.mjs | 65 +-
tests/unit/utils/gemini-web-api-mode.test.mjs | 412 +++++++++
44 files changed, 5554 insertions(+), 296 deletions(-)
delete mode 100644 src/services/apis/bard-web.mjs
create mode 100644 src/services/apis/gemini-web-transport.mjs
create mode 100644 src/services/apis/gemini-web.mjs
delete mode 100644 src/services/clients/bard/index.mjs
create mode 100644 src/services/clients/gemini-web/index.mjs
create mode 100644 src/services/clients/gemini-web/protocol.mjs
create mode 100644 src/utils/gemini-web-preset.mjs
create mode 100644 tests/unit/prettier-inspection.test.mjs
delete mode 100644 tests/unit/services/apis/bard-web.test.mjs
create mode 100644 tests/unit/services/apis/gemini-web-compat.test.mjs
create mode 100644 tests/unit/services/apis/gemini-web-protocol.test.mjs
create mode 100644 tests/unit/services/apis/gemini-web-retry.test.mjs
create mode 100644 tests/unit/services/apis/gemini-web-thinking.test.mjs
create mode 100644 tests/unit/services/apis/gemini-web.test.mjs
create mode 100644 tests/unit/services/gemini-web-i18n.test.mjs
create mode 100644 tests/unit/utils/gemini-web-api-mode.test.mjs
diff --git a/src/_locales/de/main.json b/src/_locales/de/main.json
index 8b0d204bc..444f48348 100644
--- a/src/_locales/de/main.json
+++ b/src/_locales/de/main.json
@@ -167,6 +167,49 @@
"Type": "Typ",
"Mode": "Modus",
"Custom": "Benutzerdefiniert",
+ "Extended thinking": "Erweitertes Denken",
+ "A Gemini Web API mode with this model and thinking setting already exists.": "Ein Gemini-Web-API-Modus mit diesem Modell und dieser Denkeinstellung ist bereits vorhanden.",
+ "Gemini Web: Invalid response format. The website protocol may have changed.": "Gemini Web: Ungültiges Antwortformat. Das Website-Protokoll hat sich möglicherweise geändert.",
+ "Gemini Web: Invalid response frame length.": "Gemini Web: Ungültige Antwort-Frame-Länge.",
+ "Gemini Web: Truncated response frame.": "Gemini Web: Abgeschnittener Antwort-Frame.",
+ "Gemini Web: Invalid response envelope.": "Gemini Web: Ungültige Antwort-Hüllstruktur.",
+ "Gemini Web: Invalid conversation identifier.": "Gemini Web: Ungültige Konversationskennung.",
+ "Gemini Web: Conversation identifiers changed during generation.": "Gemini Web: Die Konversationskennungen haben sich während der Generierung geändert.",
+ "Gemini Web: The website rejected the request. Check Gemini in your browser.": "Gemini Web: Die Website hat die Anfrage abgelehnt. Überprüfen Sie Gemini in Ihrem Browser.",
+ "Gemini Web: The website rejected the request ({{code}}). Check Gemini in your browser.": "Gemini Web: Die Website hat die Anfrage abgelehnt ({{code}}). Überprüfen Sie Gemini in Ihrem Browser.",
+ "Gemini Web: Invalid response payload.": "Gemini Web: Ungültige Antwortdaten.",
+ "Gemini Web: Invalid candidate identifier.": "Gemini Web: Ungültige Antwortkandidaten-Kennung.",
+ "Gemini Web: Candidate changed during generation.": "Gemini Web: Der Antwortkandidat hat sich während der Generierung geändert.",
+ "Gemini Web: Invalid text candidate.": "Gemini Web: Ungültiger Textkandidat.",
+ "Gemini Web: No text answer was received. Check Gemini in your browser.": "Gemini Web: Es wurde keine Textantwort empfangen. Überprüfen Sie Gemini in Ihrem Browser.",
+ "Gemini Web: Could not confirm that the answer finished generating.": "Gemini Web: Es konnte nicht bestätigt werden, dass die Antwort fertig generiert wurde.",
+ "Gemini Web: The answer was interrupted before completion. Check Gemini before retrying.": "Gemini Web: Die Antwort wurde vor Abschluss unterbrochen. Überprüfen Sie Gemini vor einem erneuten Versuch.",
+ "Gemini Web: Missing conversation identifiers.": "Gemini Web: Fehlende Konversationskennungen.",
+ "Gemini Web: Invalid Google account route. Start a new conversation.": "Gemini Web: Ungültige Google-Konto-Route. Starten Sie eine neue Konversation.",
+ "Gemini Web: Invalid website session data.": "Gemini Web: Ungültige Website-Sitzungsdaten.",
+ "Gemini Web: HTTP {{status}}. Check your login and limits on Gemini.": "Gemini Web: HTTP {{status}}. Überprüfen Sie Anmeldung und Limits in Gemini.",
+ "Gemini Web: Sign in to Gemini in this browser profile before trying again.": "Gemini Web: Melden Sie sich in diesem Browser-Profil bei Gemini an, bevor Sie es erneut versuchen.",
+ "Gemini Web: Empty website response.": "Gemini Web: Leere Website-Antwort.",
+ "Gemini Web: Website response is too large.": "Gemini Web: Die Website-Antwort ist zu groß.",
+ "Gemini Web: The Google account route changed. Start a new conversation.": "Gemini Web: Die Google-Konto-Route hat sich geändert. Starten Sie eine neue Konversation.",
+ "Gemini Web: The selected model is not available for this Google account.": "Gemini Web: Das ausgewählte Modell ist für dieses Google-Konto nicht verfügbar.",
+ "Gemini Web: Invalid Gemini Web model selection.": "Gemini Web: Ungültige Gemini-Web-Modellauswahl.",
+ "Gemini Web: Gemini could not load the available models for this account.": "Gemini Web: Gemini konnte die verfügbaren Modelle für dieses Konto nicht laden.",
+ "Gemini Web: Invalid Gemini model discovery response.": "Gemini Web: Ungültige Gemini-Modellerkennungsantwort.",
+ "Gemini Web: Gemini returned no available model information.": "Gemini Web: Gemini hat keine verfügbaren Modellinformationen zurückgegeben.",
+ "Gemini Web: This Google account cannot select models ({{status}}).": "Gemini Web: Dieses Google-Konto kann keine Modelle auswählen ({{status}}).",
+ "Gemini Web: Invalid conversation state. Start a new conversation.": "Gemini Web: Ungültiger Konversationsstatus. Starten Sie eine neue Konversation.",
+ "Gemini Web: This conversation has no stored Google account route. Start a new conversation.": "Gemini Web: Diese Konversation hat keine gespeicherte Google-Konto-Route. Starten Sie eine neue Konversation.",
+ "Gemini Web: Empty question.": "Gemini Web: Leere Frage.",
+ "Gemini Web: Request timed out. Check Gemini before retrying.": "Gemini Web: Zeitüberschreitung der Anfrage. Überprüfen Sie Gemini vor einem erneuten Versuch.",
+ "Gemini Web: Gemini encountered a temporary generation error. Please retry.": "Gemini Web: Bei Gemini ist ein vorübergehender Generierungsfehler aufgetreten. Bitte versuchen Sie es erneut.",
+ "Gemini Web: Gemini usage limit reached for the selected model. Check Gemini before retrying.": "Gemini Web: Das Nutzungslimit für das ausgewählte Modell wurde erreicht. Überprüfen Sie Gemini, bevor Sie es erneut versuchen.",
+ "Gemini Web: The selected model does not match this conversation. Start a new conversation.": "Gemini Web: Das ausgewählte Modell stimmt nicht mit dieser Konversation überein. Starten Sie eine neue Konversation.",
+ "Gemini Web: The selected model is unavailable or the Gemini website protocol changed.": "Gemini Web: Das ausgewählte Modell ist nicht verfügbar oder das Gemini-Webprotokoll hat sich geändert.",
+ "Gemini Web: Gemini temporarily blocked requests from this network. Try again later.": "Gemini Web: Gemini hat Anfragen aus diesem Netzwerk vorübergehend blockiert. Versuchen Sie es später erneut.",
+ "Gemini Web: This conversation can no longer be continued. Start a new conversation.": "Gemini Web: Diese Konversation kann nicht mehr fortgesetzt werden. Starten Sie eine neue Konversation.",
+ "Gemini Web: This conversation has no stored Gemini model. Start a new conversation.": "Gemini Web: Für diese Konversation ist kein Gemini-Modell gespeichert. Starten Sie eine neue Konversation.",
+ "Gemini Web: The previous Gemini request may have changed the remote conversation. Start a new ChatGPTBox conversation.": "Gemini Web: Die vorherige Gemini-Anfrage könnte die entfernte Konversation geändert haben. Starten Sie eine neue ChatGPTBox-Konversation.",
"This provider is still used by other API modes or saved conversations": "Dieser Anbieter wird noch von anderen API-Modi oder gespeicherten Unterhaltungen verwendet",
"This API key is set on the selected custom mode. Editing it here will create a dedicated provider for that mode.": "Dieser API-Schlüssel ist für den ausgewählten benutzerdefinierten Modus festgelegt. Wenn Sie ihn hier bearbeiten, wird ein dedizierter Provider für diesen Modus erstellt.",
"Use shared key": "Gemeinsamen Schlüssel verwenden",
diff --git a/src/_locales/en/main.json b/src/_locales/en/main.json
index 8756caa19..b3a9003fa 100644
--- a/src/_locales/en/main.json
+++ b/src/_locales/en/main.json
@@ -178,6 +178,49 @@
"Type": "Type",
"Mode": "Mode",
"Custom": "Custom",
+ "Extended thinking": "Extended thinking",
+ "A Gemini Web API mode with this model and thinking setting already exists.": "A Gemini Web API mode with this model and thinking setting already exists.",
+ "Gemini Web: Invalid response format. The website protocol may have changed.": "Gemini Web: Invalid response format. The website protocol may have changed.",
+ "Gemini Web: Invalid response frame length.": "Gemini Web: Invalid response frame length.",
+ "Gemini Web: Truncated response frame.": "Gemini Web: Truncated response frame.",
+ "Gemini Web: Invalid response envelope.": "Gemini Web: Invalid response envelope.",
+ "Gemini Web: Invalid conversation identifier.": "Gemini Web: Invalid conversation identifier.",
+ "Gemini Web: Conversation identifiers changed during generation.": "Gemini Web: Conversation identifiers changed during generation.",
+ "Gemini Web: The website rejected the request. Check Gemini in your browser.": "Gemini Web: The website rejected the request. Check Gemini in your browser.",
+ "Gemini Web: The website rejected the request ({{code}}). Check Gemini in your browser.": "Gemini Web: The website rejected the request ({{code}}). Check Gemini in your browser.",
+ "Gemini Web: Invalid response payload.": "Gemini Web: Invalid response payload.",
+ "Gemini Web: Invalid candidate identifier.": "Gemini Web: Invalid candidate identifier.",
+ "Gemini Web: Candidate changed during generation.": "Gemini Web: Candidate changed during generation.",
+ "Gemini Web: Invalid text candidate.": "Gemini Web: Invalid text candidate.",
+ "Gemini Web: No text answer was received. Check Gemini in your browser.": "Gemini Web: No text answer was received. Check Gemini in your browser.",
+ "Gemini Web: Could not confirm that the answer finished generating.": "Gemini Web: Could not confirm that the answer finished generating.",
+ "Gemini Web: The answer was interrupted before completion. Check Gemini before retrying.": "Gemini Web: The answer was interrupted before completion. Check Gemini before retrying.",
+ "Gemini Web: Missing conversation identifiers.": "Gemini Web: Missing conversation identifiers.",
+ "Gemini Web: Invalid Google account route. Start a new conversation.": "Gemini Web: Invalid Google account route. Start a new conversation.",
+ "Gemini Web: Invalid website session data.": "Gemini Web: Invalid website session data.",
+ "Gemini Web: HTTP {{status}}. Check your login and limits on Gemini.": "Gemini Web: HTTP {{status}}. Check your login and limits on Gemini.",
+ "Gemini Web: Sign in to Gemini in this browser profile before trying again.": "Gemini Web: Sign in to Gemini in this browser profile before trying again.",
+ "Gemini Web: Empty website response.": "Gemini Web: Empty website response.",
+ "Gemini Web: Website response is too large.": "Gemini Web: Website response is too large.",
+ "Gemini Web: The Google account route changed. Start a new conversation.": "Gemini Web: The Google account route changed. Start a new conversation.",
+ "Gemini Web: The selected model is not available for this Google account.": "Gemini Web: The selected model is not available for this Google account.",
+ "Gemini Web: Invalid Gemini Web model selection.": "Gemini Web: Invalid Gemini Web model selection.",
+ "Gemini Web: Gemini could not load the available models for this account.": "Gemini Web: Gemini could not load the available models for this account.",
+ "Gemini Web: Invalid Gemini model discovery response.": "Gemini Web: Invalid Gemini model discovery response.",
+ "Gemini Web: Gemini returned no available model information.": "Gemini Web: Gemini returned no available model information.",
+ "Gemini Web: This Google account cannot select models ({{status}}).": "Gemini Web: This Google account cannot select models ({{status}}).",
+ "Gemini Web: Invalid conversation state. Start a new conversation.": "Gemini Web: Invalid conversation state. Start a new conversation.",
+ "Gemini Web: This conversation has no stored Google account route. Start a new conversation.": "Gemini Web: This conversation has no stored Google account route. Start a new conversation.",
+ "Gemini Web: Empty question.": "Gemini Web: Empty question.",
+ "Gemini Web: Request timed out. Check Gemini before retrying.": "Gemini Web: Request timed out. Check Gemini before retrying.",
+ "Gemini Web: Gemini encountered a temporary generation error. Please retry.": "Gemini Web: Gemini encountered a temporary generation error. Please retry.",
+ "Gemini Web: Gemini usage limit reached for the selected model. Check Gemini before retrying.": "Gemini Web: Gemini usage limit reached for the selected model. Check Gemini before retrying.",
+ "Gemini Web: The selected model does not match this conversation. Start a new conversation.": "Gemini Web: The selected model does not match this conversation. Start a new conversation.",
+ "Gemini Web: The selected model is unavailable or the Gemini website protocol changed.": "Gemini Web: The selected model is unavailable or the Gemini website protocol changed.",
+ "Gemini Web: Gemini temporarily blocked requests from this network. Try again later.": "Gemini Web: Gemini temporarily blocked requests from this network. Try again later.",
+ "Gemini Web: This conversation can no longer be continued. Start a new conversation.": "Gemini Web: This conversation can no longer be continued. Start a new conversation.",
+ "Gemini Web: This conversation has no stored Gemini model. Start a new conversation.": "Gemini Web: This conversation has no stored Gemini model. Start a new conversation.",
+ "Gemini Web: The previous Gemini request may have changed the remote conversation. Start a new ChatGPTBox conversation.": "Gemini Web: The previous Gemini request may have changed the remote conversation. Start a new ChatGPTBox conversation.",
"Crop Text to ensure the input tokens do not exceed the model's limit": "Crop Text to ensure the input tokens do not exceed the model's limit",
"OpenAI (API)": "OpenAI (API)",
"Anthropic (API)": "Anthropic (API)",
diff --git a/src/_locales/es/main.json b/src/_locales/es/main.json
index c9f5b5a11..c19ec5d9f 100644
--- a/src/_locales/es/main.json
+++ b/src/_locales/es/main.json
@@ -165,6 +165,49 @@
"Type": "Tipo",
"Mode": "Modo",
"Custom": "Personalizado",
+ "Extended thinking": "Pensamiento extendido",
+ "A Gemini Web API mode with this model and thinking setting already exists.": "Ya existe un modo de API de Gemini Web con este modelo y esta configuración de razonamiento.",
+ "Gemini Web: Invalid response format. The website protocol may have changed.": "Gemini Web: Formato de respuesta no válido. Es posible que el protocolo del sitio web haya cambiado.",
+ "Gemini Web: Invalid response frame length.": "Gemini Web: Longitud de marco de respuesta no válida.",
+ "Gemini Web: Truncated response frame.": "Gemini Web: Marco de respuesta truncado.",
+ "Gemini Web: Invalid response envelope.": "Gemini Web: Contenedor de respuesta no válido.",
+ "Gemini Web: Invalid conversation identifier.": "Gemini Web: Identificador de conversación no válido.",
+ "Gemini Web: Conversation identifiers changed during generation.": "Gemini Web: Los identificadores de conversación cambiaron durante la generación.",
+ "Gemini Web: The website rejected the request. Check Gemini in your browser.": "Gemini Web: El sitio web rechazó la solicitud. Revisa Gemini en tu navegador.",
+ "Gemini Web: The website rejected the request ({{code}}). Check Gemini in your browser.": "Gemini Web: El sitio web rechazó la solicitud ({{code}}). Revisa Gemini en tu navegador.",
+ "Gemini Web: Invalid response payload.": "Gemini Web: Datos de respuesta no válidos.",
+ "Gemini Web: Invalid candidate identifier.": "Gemini Web: Identificador de candidato no válido.",
+ "Gemini Web: Candidate changed during generation.": "Gemini Web: El candidato cambió durante la generación.",
+ "Gemini Web: Invalid text candidate.": "Gemini Web: Candidato de texto no válido.",
+ "Gemini Web: No text answer was received. Check Gemini in your browser.": "Gemini Web: No se recibió una respuesta de texto. Revisa Gemini en tu navegador.",
+ "Gemini Web: Could not confirm that the answer finished generating.": "Gemini Web: No se pudo confirmar que la respuesta terminó de generarse.",
+ "Gemini Web: The answer was interrupted before completion. Check Gemini before retrying.": "Gemini Web: La respuesta se interrumpió antes de completarse. Revisa Gemini antes de reintentarlo.",
+ "Gemini Web: Missing conversation identifiers.": "Gemini Web: Faltan los identificadores de conversación.",
+ "Gemini Web: Invalid Google account route. Start a new conversation.": "Gemini Web: Ruta de cuenta de Google no válida. Inicia una nueva conversación.",
+ "Gemini Web: Invalid website session data.": "Gemini Web: Datos de sesión del sitio web no válidos.",
+ "Gemini Web: HTTP {{status}}. Check your login and limits on Gemini.": "Gemini Web: HTTP {{status}}. Revisa tu inicio de sesión y los límites en Gemini.",
+ "Gemini Web: Sign in to Gemini in this browser profile before trying again.": "Gemini Web: Inicia sesión en Gemini con este perfil de navegador antes de intentarlo de nuevo.",
+ "Gemini Web: Empty website response.": "Gemini Web: Respuesta del sitio web vacía.",
+ "Gemini Web: Website response is too large.": "Gemini Web: La respuesta del sitio web es demasiado grande.",
+ "Gemini Web: The Google account route changed. Start a new conversation.": "Gemini Web: La ruta de la cuenta de Google cambió. Inicia una nueva conversación.",
+ "Gemini Web: The selected model is not available for this Google account.": "Gemini Web: El modelo seleccionado no está disponible para esta cuenta de Google.",
+ "Gemini Web: Invalid Gemini Web model selection.": "Gemini Web: Selección de modelo de Gemini Web no válida.",
+ "Gemini Web: Gemini could not load the available models for this account.": "Gemini Web: Gemini no pudo cargar los modelos disponibles para esta cuenta.",
+ "Gemini Web: Invalid Gemini model discovery response.": "Gemini Web: Respuesta de detección de modelos de Gemini no válida.",
+ "Gemini Web: Gemini returned no available model information.": "Gemini Web: Gemini no devolvió información de modelos disponibles.",
+ "Gemini Web: This Google account cannot select models ({{status}}).": "Gemini Web: Esta cuenta de Google no puede seleccionar modelos ({{status}}).",
+ "Gemini Web: Invalid conversation state. Start a new conversation.": "Gemini Web: Estado de conversación no válido. Inicia una nueva conversación.",
+ "Gemini Web: This conversation has no stored Google account route. Start a new conversation.": "Gemini Web: Esta conversación no tiene una ruta de cuenta de Google guardada. Inicia una nueva conversación.",
+ "Gemini Web: Empty question.": "Gemini Web: Pregunta vacía.",
+ "Gemini Web: Request timed out. Check Gemini before retrying.": "Gemini Web: La solicitud caducó. Revisa Gemini antes de reintentarlo.",
+ "Gemini Web: Gemini encountered a temporary generation error. Please retry.": "Gemini Web: Gemini encontró un error temporal de generación. Inténtalo de nuevo.",
+ "Gemini Web: Gemini usage limit reached for the selected model. Check Gemini before retrying.": "Gemini Web: Se alcanzó el límite de uso del modelo seleccionado. Comprueba Gemini antes de volver a intentarlo.",
+ "Gemini Web: The selected model does not match this conversation. Start a new conversation.": "Gemini Web: El modelo seleccionado no coincide con esta conversación. Inicia una conversación nueva.",
+ "Gemini Web: The selected model is unavailable or the Gemini website protocol changed.": "Gemini Web: El modelo seleccionado no está disponible o el protocolo web de Gemini ha cambiado.",
+ "Gemini Web: Gemini temporarily blocked requests from this network. Try again later.": "Gemini Web: Gemini bloqueó temporalmente las solicitudes desde esta red. Inténtalo de nuevo más tarde.",
+ "Gemini Web: This conversation can no longer be continued. Start a new conversation.": "Gemini Web: Esta conversación ya no puede continuar. Inicia una conversación nueva.",
+ "Gemini Web: This conversation has no stored Gemini model. Start a new conversation.": "Gemini Web: Esta conversación no tiene guardado el modelo de Gemini. Inicia una conversación nueva.",
+ "Gemini Web: The previous Gemini request may have changed the remote conversation. Start a new ChatGPTBox conversation.": "Gemini Web: La solicitud anterior de Gemini puede haber cambiado la conversación remota. Inicia una nueva conversación de ChatGPTBox.",
"This provider is still used by other API modes or saved conversations": "Este proveedor todavía está siendo utilizado por otros modos de API o conversaciones guardadas",
"This API key is set on the selected custom mode. Editing it here will create a dedicated provider for that mode.": "Esta clave de API está configurada en el modo personalizado seleccionado. Si la editas aquí, se creará un proveedor dedicado para ese modo.",
"Use shared key": "Usar clave compartida",
diff --git a/src/_locales/fr/main.json b/src/_locales/fr/main.json
index 1fa86e8a3..2b6ecf4ea 100644
--- a/src/_locales/fr/main.json
+++ b/src/_locales/fr/main.json
@@ -165,6 +165,49 @@
"Type": "Type",
"Mode": "Mode",
"Custom": "Personnalisé",
+ "Extended thinking": "Réflexion étendue",
+ "A Gemini Web API mode with this model and thinking setting already exists.": "Un mode API Gemini Web avec ce modèle et ce réglage de raisonnement existe déjà.",
+ "Gemini Web: Invalid response format. The website protocol may have changed.": "Gemini Web : Format de réponse non valide. Le protocole du site web a peut-être changé.",
+ "Gemini Web: Invalid response frame length.": "Gemini Web : Longueur de trame de réponse non valide.",
+ "Gemini Web: Truncated response frame.": "Gemini Web : Trame de réponse tronquée.",
+ "Gemini Web: Invalid response envelope.": "Gemini Web : Enveloppe de réponse non valide.",
+ "Gemini Web: Invalid conversation identifier.": "Gemini Web : Identifiant de conversation non valide.",
+ "Gemini Web: Conversation identifiers changed during generation.": "Gemini Web : Les identifiants de conversation ont changé pendant la génération.",
+ "Gemini Web: The website rejected the request. Check Gemini in your browser.": "Gemini Web : Le site web a rejeté la demande. Vérifiez Gemini dans votre navigateur.",
+ "Gemini Web: The website rejected the request ({{code}}). Check Gemini in your browser.": "Gemini Web : Le site web a rejeté la demande ({{code}}). Vérifiez Gemini dans votre navigateur.",
+ "Gemini Web: Invalid response payload.": "Gemini Web : Données de réponse non valides.",
+ "Gemini Web: Invalid candidate identifier.": "Gemini Web : Identifiant de candidat non valide.",
+ "Gemini Web: Candidate changed during generation.": "Gemini Web : Le candidat a changé pendant la génération.",
+ "Gemini Web: Invalid text candidate.": "Gemini Web : Candidat textuel non valide.",
+ "Gemini Web: No text answer was received. Check Gemini in your browser.": "Gemini Web : Aucune réponse textuelle reçue. Vérifiez Gemini dans votre navigateur.",
+ "Gemini Web: Could not confirm that the answer finished generating.": "Gemini Web : Impossible de confirmer que la réponse a fini de générer.",
+ "Gemini Web: The answer was interrupted before completion. Check Gemini before retrying.": "Gemini Web : La réponse a été interrompue avant la fin. Vérifiez Gemini avant de réessayer.",
+ "Gemini Web: Missing conversation identifiers.": "Gemini Web : Identifiants de conversation manquants.",
+ "Gemini Web: Invalid Google account route. Start a new conversation.": "Gemini Web : Route de compte Google non valide. Démarrez une nouvelle conversation.",
+ "Gemini Web: Invalid website session data.": "Gemini Web : Données de session du site web non valides.",
+ "Gemini Web: HTTP {{status}}. Check your login and limits on Gemini.": "Gemini Web : HTTP {{status}}. Vérifiez votre connexion et vos limites sur Gemini.",
+ "Gemini Web: Sign in to Gemini in this browser profile before trying again.": "Gemini Web : Connectez-vous à Gemini dans ce profil de navigateur avant de réessayer.",
+ "Gemini Web: Empty website response.": "Gemini Web : Réponse du site web vide.",
+ "Gemini Web: Website response is too large.": "Gemini Web : Réponse du site web trop volumineuse.",
+ "Gemini Web: The Google account route changed. Start a new conversation.": "Gemini Web : La route du compte Google a changé. Démarrez une nouvelle conversation.",
+ "Gemini Web: The selected model is not available for this Google account.": "Gemini Web : Le modèle sélectionné n’est pas disponible pour ce compte Google.",
+ "Gemini Web: Invalid Gemini Web model selection.": "Gemini Web : Sélection de modèle Gemini Web non valide.",
+ "Gemini Web: Gemini could not load the available models for this account.": "Gemini Web : Gemini n’a pas pu charger les modèles disponibles pour ce compte.",
+ "Gemini Web: Invalid Gemini model discovery response.": "Gemini Web : Réponse de détection des modèles Gemini non valide.",
+ "Gemini Web: Gemini returned no available model information.": "Gemini Web : Gemini n’a renvoyé aucune information de modèle disponible.",
+ "Gemini Web: This Google account cannot select models ({{status}}).": "Gemini Web : Ce compte Google ne peut pas sélectionner de modèles ({{status}}).",
+ "Gemini Web: Invalid conversation state. Start a new conversation.": "Gemini Web : État de conversation non valide. Démarrez une nouvelle conversation.",
+ "Gemini Web: This conversation has no stored Google account route. Start a new conversation.": "Gemini Web : Cette conversation n’a aucune route de compte Google enregistrée. Démarrez une nouvelle conversation.",
+ "Gemini Web: Empty question.": "Gemini Web : Question vide.",
+ "Gemini Web: Request timed out. Check Gemini before retrying.": "Gemini Web : Délai de la demande dépassé. Vérifiez Gemini avant de réessayer.",
+ "Gemini Web: Gemini encountered a temporary generation error. Please retry.": "Gemini Web : Gemini a rencontré une erreur temporaire de génération. Veuillez réessayer.",
+ "Gemini Web: Gemini usage limit reached for the selected model. Check Gemini before retrying.": "Gemini Web : La limite d’utilisation du modèle sélectionné a été atteinte. Vérifiez Gemini avant de réessayer.",
+ "Gemini Web: The selected model does not match this conversation. Start a new conversation.": "Gemini Web : Le modèle sélectionné ne correspond pas à cette conversation. Démarrez une nouvelle conversation.",
+ "Gemini Web: The selected model is unavailable or the Gemini website protocol changed.": "Gemini Web : Le modèle sélectionné est indisponible ou le protocole web de Gemini a changé.",
+ "Gemini Web: Gemini temporarily blocked requests from this network. Try again later.": "Gemini Web : Gemini a temporairement bloqué les requêtes provenant de ce réseau. Réessayez plus tard.",
+ "Gemini Web: This conversation can no longer be continued. Start a new conversation.": "Gemini Web : Cette conversation ne peut plus être poursuivie. Démarrez une nouvelle conversation.",
+ "Gemini Web: This conversation has no stored Gemini model. Start a new conversation.": "Gemini Web : Aucun modèle Gemini n’est enregistré pour cette conversation. Démarrez une nouvelle conversation.",
+ "Gemini Web: The previous Gemini request may have changed the remote conversation. Start a new ChatGPTBox conversation.": "Gemini Web : La requête Gemini précédente a peut-être modifié la conversation distante. Démarrez une nouvelle conversation ChatGPTBox.",
"This provider is still used by other API modes or saved conversations": "Ce fournisseur est encore utilisé par d'autres modes d'API ou des conversations enregistrées",
"This API key is set on the selected custom mode. Editing it here will create a dedicated provider for that mode.": "Cette clé API est définie sur le mode personnalisé sélectionné. La modifier ici créera un fournisseur dédié pour ce mode.",
"Use shared key": "Utiliser la clé partagée",
diff --git a/src/_locales/id/main.json b/src/_locales/id/main.json
index 5267098d2..8e235815d 100644
--- a/src/_locales/id/main.json
+++ b/src/_locales/id/main.json
@@ -165,6 +165,49 @@
"Type": "Jenis",
"Mode": "Mode",
"Custom": "Kustom",
+ "Extended thinking": "Pemikiran diperluas",
+ "A Gemini Web API mode with this model and thinking setting already exists.": "Mode API Gemini Web dengan model dan pengaturan penalaran ini sudah ada.",
+ "Gemini Web: Invalid response format. The website protocol may have changed.": "Gemini Web: Format respons tidak valid. Protokol situs web mungkin telah berubah.",
+ "Gemini Web: Invalid response frame length.": "Gemini Web: Panjang bingkai respons tidak valid.",
+ "Gemini Web: Truncated response frame.": "Gemini Web: Bingkai respons terpotong.",
+ "Gemini Web: Invalid response envelope.": "Gemini Web: Amplop respons tidak valid.",
+ "Gemini Web: Invalid conversation identifier.": "Gemini Web: Pengenal percakapan tidak valid.",
+ "Gemini Web: Conversation identifiers changed during generation.": "Gemini Web: Pengenal percakapan berubah selama pembuatan.",
+ "Gemini Web: The website rejected the request. Check Gemini in your browser.": "Gemini Web: Situs web menolak permintaan. Periksa Gemini di browser Anda.",
+ "Gemini Web: The website rejected the request ({{code}}). Check Gemini in your browser.": "Gemini Web: Situs web menolak permintaan ({{code}}). Periksa Gemini di browser Anda.",
+ "Gemini Web: Invalid response payload.": "Gemini Web: Muatan respons tidak valid.",
+ "Gemini Web: Invalid candidate identifier.": "Gemini Web: Pengenal kandidat tidak valid.",
+ "Gemini Web: Candidate changed during generation.": "Gemini Web: Kandidat berubah selama pembuatan.",
+ "Gemini Web: Invalid text candidate.": "Gemini Web: Kandidat teks tidak valid.",
+ "Gemini Web: No text answer was received. Check Gemini in your browser.": "Gemini Web: Tidak ada jawaban teks yang diterima. Periksa Gemini di browser Anda.",
+ "Gemini Web: Could not confirm that the answer finished generating.": "Gemini Web: Tidak dapat memastikan bahwa jawaban selesai dibuat.",
+ "Gemini Web: The answer was interrupted before completion. Check Gemini before retrying.": "Gemini Web: Jawaban terputus sebelum selesai. Periksa Gemini sebelum mencoba lagi.",
+ "Gemini Web: Missing conversation identifiers.": "Gemini Web: Pengenal percakapan tidak ada.",
+ "Gemini Web: Invalid Google account route. Start a new conversation.": "Gemini Web: Rute akun Google tidak valid. Mulai percakapan baru.",
+ "Gemini Web: Invalid website session data.": "Gemini Web: Data sesi situs web tidak valid.",
+ "Gemini Web: HTTP {{status}}. Check your login and limits on Gemini.": "Gemini Web: HTTP {{status}}. Periksa login dan batas Anda di Gemini.",
+ "Gemini Web: Sign in to Gemini in this browser profile before trying again.": "Gemini Web: Masuk ke Gemini di profil browser ini sebelum mencoba lagi.",
+ "Gemini Web: Empty website response.": "Gemini Web: Respons situs web kosong.",
+ "Gemini Web: Website response is too large.": "Gemini Web: Respons situs web terlalu besar.",
+ "Gemini Web: The Google account route changed. Start a new conversation.": "Gemini Web: Rute akun Google berubah. Mulai percakapan baru.",
+ "Gemini Web: The selected model is not available for this Google account.": "Gemini Web: Model yang dipilih tidak tersedia untuk akun Google ini.",
+ "Gemini Web: Invalid Gemini Web model selection.": "Gemini Web: Pemilihan model Gemini Web tidak valid.",
+ "Gemini Web: Gemini could not load the available models for this account.": "Gemini Web: Gemini tidak dapat memuat model yang tersedia untuk akun ini.",
+ "Gemini Web: Invalid Gemini model discovery response.": "Gemini Web: Respons deteksi model Gemini tidak valid.",
+ "Gemini Web: Gemini returned no available model information.": "Gemini Web: Gemini tidak mengembalikan informasi model yang tersedia.",
+ "Gemini Web: This Google account cannot select models ({{status}}).": "Gemini Web: Akun Google ini tidak dapat memilih model ({{status}}).",
+ "Gemini Web: Invalid conversation state. Start a new conversation.": "Gemini Web: Status percakapan tidak valid. Mulai percakapan baru.",
+ "Gemini Web: This conversation has no stored Google account route. Start a new conversation.": "Gemini Web: Percakapan ini tidak memiliki rute akun Google yang tersimpan. Mulai percakapan baru.",
+ "Gemini Web: Empty question.": "Gemini Web: Pertanyaan kosong.",
+ "Gemini Web: Request timed out. Check Gemini before retrying.": "Gemini Web: Permintaan kedaluwarsa. Periksa Gemini sebelum mencoba lagi.",
+ "Gemini Web: Gemini encountered a temporary generation error. Please retry.": "Gemini Web: Gemini mengalami kesalahan pembuatan sementara. Silakan coba lagi.",
+ "Gemini Web: Gemini usage limit reached for the selected model. Check Gemini before retrying.": "Gemini Web: Batas penggunaan untuk model yang dipilih telah tercapai. Periksa Gemini sebelum mencoba lagi.",
+ "Gemini Web: The selected model does not match this conversation. Start a new conversation.": "Gemini Web: Model yang dipilih tidak cocok dengan percakapan ini. Mulai percakapan baru.",
+ "Gemini Web: The selected model is unavailable or the Gemini website protocol changed.": "Gemini Web: Model yang dipilih tidak tersedia atau protokol web Gemini telah berubah.",
+ "Gemini Web: Gemini temporarily blocked requests from this network. Try again later.": "Gemini Web: Gemini untuk sementara memblokir permintaan dari jaringan ini. Coba lagi nanti.",
+ "Gemini Web: This conversation can no longer be continued. Start a new conversation.": "Gemini Web: Percakapan ini tidak dapat dilanjutkan lagi. Mulai percakapan baru.",
+ "Gemini Web: This conversation has no stored Gemini model. Start a new conversation.": "Gemini Web: Percakapan ini tidak memiliki model Gemini yang tersimpan. Mulai percakapan baru.",
+ "Gemini Web: The previous Gemini request may have changed the remote conversation. Start a new ChatGPTBox conversation.": "Gemini Web: Permintaan Gemini sebelumnya mungkin telah mengubah percakapan jarak jauh. Mulai percakapan ChatGPTBox baru.",
"This provider is still used by other API modes or saved conversations": "Penyedia ini masih digunakan oleh mode API lain atau percakapan yang tersimpan",
"This API key is set on the selected custom mode. Editing it here will create a dedicated provider for that mode.": "Kunci API ini ditetapkan pada mode kustom yang dipilih. Mengeditnya di sini akan membuat penyedia khusus untuk mode tersebut.",
"Use shared key": "Gunakan kunci bersama",
diff --git a/src/_locales/it/main.json b/src/_locales/it/main.json
index 4a592ff01..4b9d05e97 100644
--- a/src/_locales/it/main.json
+++ b/src/_locales/it/main.json
@@ -165,6 +165,49 @@
"Type": "Tipo",
"Mode": "Modalità",
"Custom": "Personalizzato",
+ "Extended thinking": "Ragionamento esteso",
+ "A Gemini Web API mode with this model and thinking setting already exists.": "Esiste già una modalità API Gemini Web con questo modello e questa impostazione di ragionamento.",
+ "Gemini Web: Invalid response format. The website protocol may have changed.": "Gemini Web: Formato di risposta non valido. Il protocollo del sito web potrebbe essere cambiato.",
+ "Gemini Web: Invalid response frame length.": "Gemini Web: Lunghezza del frame di risposta non valida.",
+ "Gemini Web: Truncated response frame.": "Gemini Web: Frame di risposta troncato.",
+ "Gemini Web: Invalid response envelope.": "Gemini Web: Busta di risposta non valida.",
+ "Gemini Web: Invalid conversation identifier.": "Gemini Web: Identificatore di conversazione non valido.",
+ "Gemini Web: Conversation identifiers changed during generation.": "Gemini Web: Gli identificatori di conversazione sono cambiati durante la generazione.",
+ "Gemini Web: The website rejected the request. Check Gemini in your browser.": "Gemini Web: Il sito web ha rifiutato la richiesta. Controlla Gemini nel tuo browser.",
+ "Gemini Web: The website rejected the request ({{code}}). Check Gemini in your browser.": "Gemini Web: Il sito web ha rifiutato la richiesta ({{code}}). Controlla Gemini nel tuo browser.",
+ "Gemini Web: Invalid response payload.": "Gemini Web: Dati di risposta non validi.",
+ "Gemini Web: Invalid candidate identifier.": "Gemini Web: Identificatore di candidato non valido.",
+ "Gemini Web: Candidate changed during generation.": "Gemini Web: Il candidato è cambiato durante la generazione.",
+ "Gemini Web: Invalid text candidate.": "Gemini Web: Candidato testuale non valido.",
+ "Gemini Web: No text answer was received. Check Gemini in your browser.": "Gemini Web: Nessuna risposta testuale ricevuta. Controlla Gemini nel tuo browser.",
+ "Gemini Web: Could not confirm that the answer finished generating.": "Gemini Web: Impossibile confermare che la risposta abbia terminato la generazione.",
+ "Gemini Web: The answer was interrupted before completion. Check Gemini before retrying.": "Gemini Web: La risposta è stata interrotta prima del completamento. Controlla Gemini prima di riprovare.",
+ "Gemini Web: Missing conversation identifiers.": "Gemini Web: Identificatori di conversazione mancanti.",
+ "Gemini Web: Invalid Google account route. Start a new conversation.": "Gemini Web: Percorso dell’account Google non valido. Avvia una nuova conversazione.",
+ "Gemini Web: Invalid website session data.": "Gemini Web: Dati di sessione del sito web non validi.",
+ "Gemini Web: HTTP {{status}}. Check your login and limits on Gemini.": "Gemini Web: HTTP {{status}}. Controlla accesso e limiti su Gemini.",
+ "Gemini Web: Sign in to Gemini in this browser profile before trying again.": "Gemini Web: Accedi a Gemini in questo profilo del browser prima di riprovare.",
+ "Gemini Web: Empty website response.": "Gemini Web: Risposta del sito web vuota.",
+ "Gemini Web: Website response is too large.": "Gemini Web: Risposta del sito web troppo grande.",
+ "Gemini Web: The Google account route changed. Start a new conversation.": "Gemini Web: Il percorso dell’account Google è cambiato. Avvia una nuova conversazione.",
+ "Gemini Web: The selected model is not available for this Google account.": "Gemini Web: Il modello selezionato non è disponibile per questo account Google.",
+ "Gemini Web: Invalid Gemini Web model selection.": "Gemini Web: Selezione del modello Gemini Web non valida.",
+ "Gemini Web: Gemini could not load the available models for this account.": "Gemini Web: Gemini non ha potuto caricare i modelli disponibili per questo account.",
+ "Gemini Web: Invalid Gemini model discovery response.": "Gemini Web: Risposta di rilevamento modelli Gemini non valida.",
+ "Gemini Web: Gemini returned no available model information.": "Gemini Web: Gemini non ha restituito informazioni sui modelli disponibili.",
+ "Gemini Web: This Google account cannot select models ({{status}}).": "Gemini Web: Questo account Google non può selezionare modelli ({{status}}).",
+ "Gemini Web: Invalid conversation state. Start a new conversation.": "Gemini Web: Stato della conversazione non valido. Avvia una nuova conversazione.",
+ "Gemini Web: This conversation has no stored Google account route. Start a new conversation.": "Gemini Web: Questa conversazione non ha un percorso dell’account Google salvato. Avvia una nuova conversazione.",
+ "Gemini Web: Empty question.": "Gemini Web: Domanda vuota.",
+ "Gemini Web: Request timed out. Check Gemini before retrying.": "Gemini Web: Richiesta scaduta. Controlla Gemini prima di riprovare.",
+ "Gemini Web: Gemini encountered a temporary generation error. Please retry.": "Gemini Web: Gemini ha riscontrato un errore temporaneo di generazione. Riprova.",
+ "Gemini Web: Gemini usage limit reached for the selected model. Check Gemini before retrying.": "Gemini Web: È stato raggiunto il limite di utilizzo per il modello selezionato. Controlla Gemini prima di riprovare.",
+ "Gemini Web: The selected model does not match this conversation. Start a new conversation.": "Gemini Web: Il modello selezionato non corrisponde a questa conversazione. Avvia una nuova conversazione.",
+ "Gemini Web: The selected model is unavailable or the Gemini website protocol changed.": "Gemini Web: Il modello selezionato non è disponibile oppure il protocollo web di Gemini è cambiato.",
+ "Gemini Web: Gemini temporarily blocked requests from this network. Try again later.": "Gemini Web: Gemini ha bloccato temporaneamente le richieste da questa rete. Riprova più tardi.",
+ "Gemini Web: This conversation can no longer be continued. Start a new conversation.": "Gemini Web: Questa conversazione non può più essere continuata. Avvia una nuova conversazione.",
+ "Gemini Web: This conversation has no stored Gemini model. Start a new conversation.": "Gemini Web: Per questa conversazione non è memorizzato alcun modello Gemini. Avvia una nuova conversazione.",
+ "Gemini Web: The previous Gemini request may have changed the remote conversation. Start a new ChatGPTBox conversation.": "Gemini Web: La richiesta Gemini precedente potrebbe aver modificato la conversazione remota. Avvia una nuova conversazione ChatGPTBox.",
"This provider is still used by other API modes or saved conversations": "Questo provider è ancora utilizzato da altre modalità API o conversazioni salvate",
"This API key is set on the selected custom mode. Editing it here will create a dedicated provider for that mode.": "Questa chiave API è impostata nella modalità personalizzata selezionata. Modificandola qui verrà creato un provider dedicato per quella modalità.",
"Use shared key": "Usa la chiave condivisa",
diff --git a/src/_locales/ja/main.json b/src/_locales/ja/main.json
index 91c960949..c024956c9 100644
--- a/src/_locales/ja/main.json
+++ b/src/_locales/ja/main.json
@@ -165,6 +165,49 @@
"Type": "タイプ",
"Mode": "モード",
"Custom": "カスタム",
+ "Extended thinking": "拡張思考",
+ "A Gemini Web API mode with this model and thinking setting already exists.": "このモデルと思考設定の Gemini Web API モードはすでに存在します。",
+ "Gemini Web: Invalid response format. The website protocol may have changed.": "Gemini Web: 応答形式が無効です。Webサイトのプロトコルが変更された可能性があります。",
+ "Gemini Web: Invalid response frame length.": "Gemini Web: 応答フレームの長さが無効です。",
+ "Gemini Web: Truncated response frame.": "Gemini Web: 応答フレームが切り詰められています。",
+ "Gemini Web: Invalid response envelope.": "Gemini Web: 応答エンベロープが無効です。",
+ "Gemini Web: Invalid conversation identifier.": "Gemini Web: 会話IDが無効です。",
+ "Gemini Web: Conversation identifiers changed during generation.": "Gemini Web: 生成中に会話IDが変更されました。",
+ "Gemini Web: The website rejected the request. Check Gemini in your browser.": "Gemini Web: Webサイトがリクエストを拒否しました。ブラウザでGeminiを確認してください。",
+ "Gemini Web: The website rejected the request ({{code}}). Check Gemini in your browser.": "Gemini Web: Webサイトがリクエストを拒否しました({{code}})。ブラウザでGeminiを確認してください。",
+ "Gemini Web: Invalid response payload.": "Gemini Web: 応答ペイロードが無効です。",
+ "Gemini Web: Invalid candidate identifier.": "Gemini Web: 候補IDが無効です。",
+ "Gemini Web: Candidate changed during generation.": "Gemini Web: 生成中に候補が変更されました。",
+ "Gemini Web: Invalid text candidate.": "Gemini Web: テキスト候補が無効です。",
+ "Gemini Web: No text answer was received. Check Gemini in your browser.": "Gemini Web: テキストの回答を受信できませんでした。ブラウザでGeminiを確認してください。",
+ "Gemini Web: Could not confirm that the answer finished generating.": "Gemini Web: 回答の生成が完了したことを確認できませんでした。",
+ "Gemini Web: The answer was interrupted before completion. Check Gemini before retrying.": "Gemini Web: 回答が完了前に中断されました。再試行する前にGeminiを確認してください。",
+ "Gemini Web: Missing conversation identifiers.": "Gemini Web: 会話IDがありません。",
+ "Gemini Web: Invalid Google account route. Start a new conversation.": "Gemini Web: Googleアカウントのルートが無効です。新しい会話を開始してください。",
+ "Gemini Web: Invalid website session data.": "Gemini Web: Webサイトのセッションデータが無効です。",
+ "Gemini Web: HTTP {{status}}. Check your login and limits on Gemini.": "Gemini Web: HTTP {{status}}。Geminiでのログインと制限を確認してください。",
+ "Gemini Web: Sign in to Gemini in this browser profile before trying again.": "Gemini Web: 再試行する前に、このブラウザプロファイルでGeminiにログインしてください。",
+ "Gemini Web: Empty website response.": "Gemini Web: Webサイトの応答が空です。",
+ "Gemini Web: Website response is too large.": "Gemini Web: Webサイトの応答が大きすぎます。",
+ "Gemini Web: The Google account route changed. Start a new conversation.": "Gemini Web: Googleアカウントのルートが変更されました。新しい会話を開始してください。",
+ "Gemini Web: The selected model is not available for this Google account.": "Gemini Web: 選択したモデルはこのGoogleアカウントでは利用できません。",
+ "Gemini Web: Invalid Gemini Web model selection.": "Gemini Web: Gemini Webのモデル選択が無効です。",
+ "Gemini Web: Gemini could not load the available models for this account.": "Gemini Web: このアカウントで利用可能なモデルを読み込めませんでした。",
+ "Gemini Web: Invalid Gemini model discovery response.": "Gemini Web: Geminiのモデル検出応答が無効です。",
+ "Gemini Web: Gemini returned no available model information.": "Gemini Web: Geminiから利用可能なモデル情報が返されませんでした。",
+ "Gemini Web: This Google account cannot select models ({{status}}).": "Gemini Web: このGoogleアカウントではモデルを選択できません({{status}})。",
+ "Gemini Web: Invalid conversation state. Start a new conversation.": "Gemini Web: 会話の状態が無効です。新しい会話を開始してください。",
+ "Gemini Web: This conversation has no stored Google account route. Start a new conversation.": "Gemini Web: この会話には保存されたGoogleアカウントのルートがありません。新しい会話を開始してください。",
+ "Gemini Web: Empty question.": "Gemini Web: 質問が空です。",
+ "Gemini Web: Request timed out. Check Gemini before retrying.": "Gemini Web: リクエストがタイムアウトしました。再試行する前にGeminiを確認してください。",
+ "Gemini Web: Gemini encountered a temporary generation error. Please retry.": "Gemini Web: Gemini で一時的な生成エラーが発生しました。もう一度お試しください。",
+ "Gemini Web: Gemini usage limit reached for the selected model. Check Gemini before retrying.": "Gemini Web: 選択したモデルの使用上限に達しました。Gemini の状態を確認してから再試行してください。",
+ "Gemini Web: The selected model does not match this conversation. Start a new conversation.": "Gemini Web: 選択したモデルはこの会話と一致しません。新しい会話を開始してください。",
+ "Gemini Web: The selected model is unavailable or the Gemini website protocol changed.": "Gemini Web: 選択したモデルを利用できないか、Gemini の Web プロトコルが変更されています。",
+ "Gemini Web: Gemini temporarily blocked requests from this network. Try again later.": "Gemini Web: このネットワークからのリクエストは Gemini によって一時的にブロックされています。後でもう一度お試しください。",
+ "Gemini Web: This conversation can no longer be continued. Start a new conversation.": "Gemini Web: この会話はこれ以上続行できません。新しい会話を開始してください。",
+ "Gemini Web: This conversation has no stored Gemini model. Start a new conversation.": "Gemini Web: この会話には保存された Gemini モデル情報がありません。新しい会話を開始してください。",
+ "Gemini Web: The previous Gemini request may have changed the remote conversation. Start a new ChatGPTBox conversation.": "Gemini Web: 前回の Gemini リクエストによってリモート会話が変更された可能性があります。新しい ChatGPTBox の会話を開始してください。",
"This provider is still used by other API modes or saved conversations": "このプロバイダーは他の API モードまたは保存済みの会話でまだ使用されています",
"This API key is set on the selected custom mode. Editing it here will create a dedicated provider for that mode.": "この API キーは選択中のカスタムモードに設定されています。ここで編集すると、そのモード専用のプロバイダーが作成されます。",
"Use shared key": "共有キーを使用",
diff --git a/src/_locales/ko/main.json b/src/_locales/ko/main.json
index 252ed15f8..cf27c8d34 100644
--- a/src/_locales/ko/main.json
+++ b/src/_locales/ko/main.json
@@ -169,6 +169,49 @@
"Type": "유형",
"Mode": "모드",
"Custom": "사용자 정의",
+ "Extended thinking": "확장 사고",
+ "A Gemini Web API mode with this model and thinking setting already exists.": "이 모델과 사고 설정을 사용하는 Gemini Web API 모드가 이미 있습니다.",
+ "Gemini Web: Invalid response format. The website protocol may have changed.": "Gemini 웹: 응답 형식이 올바르지 않습니다. 웹사이트 프로토콜이 변경되었을 수 있습니다.",
+ "Gemini Web: Invalid response frame length.": "Gemini 웹: 응답 프레임 길이가 올바르지 않습니다.",
+ "Gemini Web: Truncated response frame.": "Gemini 웹: 응답 프레임이 잘렸습니다.",
+ "Gemini Web: Invalid response envelope.": "Gemini 웹: 응답 엔벨로프가 올바르지 않습니다.",
+ "Gemini Web: Invalid conversation identifier.": "Gemini 웹: 대화 식별자가 올바르지 않습니다.",
+ "Gemini Web: Conversation identifiers changed during generation.": "Gemini 웹: 생성 중에 대화 식별자가 변경되었습니다.",
+ "Gemini Web: The website rejected the request. Check Gemini in your browser.": "Gemini 웹: 웹사이트에서 요청을 거부했습니다. 브라우저에서 Gemini를 확인하세요.",
+ "Gemini Web: The website rejected the request ({{code}}). Check Gemini in your browser.": "Gemini 웹: 웹사이트에서 요청을 거부했습니다({{code}}). 브라우저에서 Gemini를 확인하세요.",
+ "Gemini Web: Invalid response payload.": "Gemini 웹: 응답 페이로드가 올바르지 않습니다.",
+ "Gemini Web: Invalid candidate identifier.": "Gemini 웹: 후보 식별자가 올바르지 않습니다.",
+ "Gemini Web: Candidate changed during generation.": "Gemini 웹: 생성 중에 후보가 변경되었습니다.",
+ "Gemini Web: Invalid text candidate.": "Gemini 웹: 텍스트 후보가 올바르지 않습니다.",
+ "Gemini Web: No text answer was received. Check Gemini in your browser.": "Gemini 웹: 텍스트 답변을 받지 못했습니다. 브라우저에서 Gemini를 확인하세요.",
+ "Gemini Web: Could not confirm that the answer finished generating.": "Gemini 웹: 답변이 완전히 생성되었는지 확인할 수 없습니다.",
+ "Gemini Web: The answer was interrupted before completion. Check Gemini before retrying.": "Gemini 웹: 답변이 완료되기 전에 중단되었습니다. 다시 시도하기 전에 Gemini를 확인하세요.",
+ "Gemini Web: Missing conversation identifiers.": "Gemini 웹: 대화 식별자가 없습니다.",
+ "Gemini Web: Invalid Google account route. Start a new conversation.": "Gemini 웹: Google 계정 경로가 올바르지 않습니다. 새 대화를 시작하세요.",
+ "Gemini Web: Invalid website session data.": "Gemini 웹: 웹사이트 세션 데이터가 올바르지 않습니다.",
+ "Gemini Web: HTTP {{status}}. Check your login and limits on Gemini.": "Gemini 웹: HTTP {{status}}. Gemini의 로그인과 한도를 확인하세요.",
+ "Gemini Web: Sign in to Gemini in this browser profile before trying again.": "Gemini 웹: 다시 시도하기 전에 이 브라우저 프로필에서 Gemini에 로그인하세요.",
+ "Gemini Web: Empty website response.": "Gemini 웹: 웹사이트 응답이 비어 있습니다.",
+ "Gemini Web: Website response is too large.": "Gemini 웹: 웹사이트 응답이 너무 큽니다.",
+ "Gemini Web: The Google account route changed. Start a new conversation.": "Gemini 웹: Google 계정 경로가 변경되었습니다. 새 대화를 시작하세요.",
+ "Gemini Web: The selected model is not available for this Google account.": "Gemini 웹: 선택한 모델은 이 Google 계정에서 사용할 수 없습니다.",
+ "Gemini Web: Invalid Gemini Web model selection.": "Gemini 웹: Gemini 웹 모델 선택이 올바르지 않습니다.",
+ "Gemini Web: Gemini could not load the available models for this account.": "Gemini 웹: 이 계정에서 사용 가능한 모델을 불러오지 못했습니다.",
+ "Gemini Web: Invalid Gemini model discovery response.": "Gemini 웹: Gemini 모델 검색 응답이 올바르지 않습니다.",
+ "Gemini Web: Gemini returned no available model information.": "Gemini 웹: Gemini에서 사용 가능한 모델 정보를 반환하지 않았습니다.",
+ "Gemini Web: This Google account cannot select models ({{status}}).": "Gemini 웹: 이 Google 계정에서는 모델을 선택할 수 없습니다({{status}}).",
+ "Gemini Web: Invalid conversation state. Start a new conversation.": "Gemini 웹: 대화 상태가 올바르지 않습니다. 새 대화를 시작하세요.",
+ "Gemini Web: This conversation has no stored Google account route. Start a new conversation.": "Gemini 웹: 이 대화에는 저장된 Google 계정 경로가 없습니다. 새 대화를 시작하세요.",
+ "Gemini Web: Empty question.": "Gemini 웹: 질문이 비어 있습니다.",
+ "Gemini Web: Request timed out. Check Gemini before retrying.": "Gemini 웹: 요청 시간이 초과되었습니다. 다시 시도하기 전에 Gemini를 확인하세요.",
+ "Gemini Web: Gemini encountered a temporary generation error. Please retry.": "Gemini Web: Gemini에서 일시적인 생성 오류가 발생했습니다. 다시 시도하세요.",
+ "Gemini Web: Gemini usage limit reached for the selected model. Check Gemini before retrying.": "Gemini Web: 선택한 모델의 사용 한도에 도달했습니다. 다시 시도하기 전에 Gemini를 확인하세요.",
+ "Gemini Web: The selected model does not match this conversation. Start a new conversation.": "Gemini Web: 선택한 모델이 이 대화와 일치하지 않습니다. 새 대화를 시작하세요.",
+ "Gemini Web: The selected model is unavailable or the Gemini website protocol changed.": "Gemini Web: 선택한 모델을 사용할 수 없거나 Gemini 웹 프로토콜이 변경되었습니다.",
+ "Gemini Web: Gemini temporarily blocked requests from this network. Try again later.": "Gemini Web: Gemini가 이 네트워크의 요청을 일시적으로 차단했습니다. 나중에 다시 시도하세요.",
+ "Gemini Web: This conversation can no longer be continued. Start a new conversation.": "Gemini Web: 이 대화를 더 이상 계속할 수 없습니다. 새 대화를 시작하세요.",
+ "Gemini Web: This conversation has no stored Gemini model. Start a new conversation.": "Gemini Web: 이 대화에 저장된 Gemini 모델 정보가 없습니다. 새 대화를 시작하세요.",
+ "Gemini Web: The previous Gemini request may have changed the remote conversation. Start a new ChatGPTBox conversation.": "Gemini Web: 이전 Gemini 요청으로 원격 대화가 변경되었을 수 있습니다. 새 ChatGPTBox 대화를 시작하세요.",
"This provider is still used by other API modes or saved conversations": "이 공급자는 아직 다른 API 모드 또는 저장된 대화에서 사용 중입니다",
"This API key is set on the selected custom mode. Editing it here will create a dedicated provider for that mode.": "이 API 키는 선택한 사용자 지정 모드에 설정되어 있습니다. 여기서 편집하면 해당 모드 전용 provider가 생성됩니다.",
"Use shared key": "공유 키 사용",
diff --git a/src/_locales/pt/main.json b/src/_locales/pt/main.json
index b3379c159..e4b31e315 100644
--- a/src/_locales/pt/main.json
+++ b/src/_locales/pt/main.json
@@ -165,6 +165,49 @@
"Type": "Tipo",
"Mode": "Modo",
"Custom": "Personalizado",
+ "Extended thinking": "Pensamento estendido",
+ "A Gemini Web API mode with this model and thinking setting already exists.": "Já existe um modo de API do Gemini Web com este modelo e esta configuração de raciocínio.",
+ "Gemini Web: Invalid response format. The website protocol may have changed.": "Gemini Web: Formato de resposta inválido. O protocolo do site pode ter mudado.",
+ "Gemini Web: Invalid response frame length.": "Gemini Web: Comprimento do quadro de resposta inválido.",
+ "Gemini Web: Truncated response frame.": "Gemini Web: Quadro de resposta truncado.",
+ "Gemini Web: Invalid response envelope.": "Gemini Web: Envelope de resposta inválido.",
+ "Gemini Web: Invalid conversation identifier.": "Gemini Web: Identificador de conversa inválido.",
+ "Gemini Web: Conversation identifiers changed during generation.": "Gemini Web: Os identificadores de conversa mudaram durante a geração.",
+ "Gemini Web: The website rejected the request. Check Gemini in your browser.": "Gemini Web: O site rejeitou a solicitação. Verifique o Gemini no seu navegador.",
+ "Gemini Web: The website rejected the request ({{code}}). Check Gemini in your browser.": "Gemini Web: O site rejeitou a solicitação ({{code}}). Verifique o Gemini no seu navegador.",
+ "Gemini Web: Invalid response payload.": "Gemini Web: Dados de resposta inválidos.",
+ "Gemini Web: Invalid candidate identifier.": "Gemini Web: Identificador de candidato inválido.",
+ "Gemini Web: Candidate changed during generation.": "Gemini Web: O candidato mudou durante a geração.",
+ "Gemini Web: Invalid text candidate.": "Gemini Web: Candidato de texto inválido.",
+ "Gemini Web: No text answer was received. Check Gemini in your browser.": "Gemini Web: Nenhuma resposta de texto recebida. Verifique o Gemini no seu navegador.",
+ "Gemini Web: Could not confirm that the answer finished generating.": "Gemini Web: Não foi possível confirmar que a resposta terminou de ser gerada.",
+ "Gemini Web: The answer was interrupted before completion. Check Gemini before retrying.": "Gemini Web: A resposta foi interrompida antes da conclusão. Verifique o Gemini antes de tentar de novo.",
+ "Gemini Web: Missing conversation identifiers.": "Gemini Web: Identificadores de conversa ausentes.",
+ "Gemini Web: Invalid Google account route. Start a new conversation.": "Gemini Web: Rota da conta Google inválida. Inicie uma nova conversa.",
+ "Gemini Web: Invalid website session data.": "Gemini Web: Dados de sessão do site inválidos.",
+ "Gemini Web: HTTP {{status}}. Check your login and limits on Gemini.": "Gemini Web: HTTP {{status}}. Verifique seu login e os limites no Gemini.",
+ "Gemini Web: Sign in to Gemini in this browser profile before trying again.": "Gemini Web: Faça login no Gemini neste perfil do navegador antes de tentar de novo.",
+ "Gemini Web: Empty website response.": "Gemini Web: Resposta do site vazia.",
+ "Gemini Web: Website response is too large.": "Gemini Web: Resposta do site muito grande.",
+ "Gemini Web: The Google account route changed. Start a new conversation.": "Gemini Web: A rota da conta Google mudou. Inicie uma nova conversa.",
+ "Gemini Web: The selected model is not available for this Google account.": "Gemini Web: O modelo selecionado não está disponível para esta conta Google.",
+ "Gemini Web: Invalid Gemini Web model selection.": "Gemini Web: Seleção de modelo do Gemini Web inválida.",
+ "Gemini Web: Gemini could not load the available models for this account.": "Gemini Web: O Gemini não conseguiu carregar os modelos disponíveis para esta conta.",
+ "Gemini Web: Invalid Gemini model discovery response.": "Gemini Web: Resposta de detecção de modelos do Gemini inválida.",
+ "Gemini Web: Gemini returned no available model information.": "Gemini Web: O Gemini não retornou informações de modelos disponíveis.",
+ "Gemini Web: This Google account cannot select models ({{status}}).": "Gemini Web: Esta conta Google não pode selecionar modelos ({{status}}).",
+ "Gemini Web: Invalid conversation state. Start a new conversation.": "Gemini Web: Estado de conversa inválido. Inicie uma nova conversa.",
+ "Gemini Web: This conversation has no stored Google account route. Start a new conversation.": "Gemini Web: Esta conversa não tem uma rota de conta Google guardada. Inicie uma nova conversa.",
+ "Gemini Web: Empty question.": "Gemini Web: Pergunta vazia.",
+ "Gemini Web: Request timed out. Check Gemini before retrying.": "Gemini Web: A solicitação expirou. Verifique o Gemini antes de tentar de novo.",
+ "Gemini Web: Gemini encountered a temporary generation error. Please retry.": "Gemini Web: O Gemini encontrou um erro temporário de geração. Tente novamente.",
+ "Gemini Web: Gemini usage limit reached for the selected model. Check Gemini before retrying.": "Gemini Web: O limite de uso do modelo selecionado foi atingido. Verifique o Gemini antes de tentar novamente.",
+ "Gemini Web: The selected model does not match this conversation. Start a new conversation.": "Gemini Web: O modelo selecionado não corresponde a esta conversa. Inicie uma nova conversa.",
+ "Gemini Web: The selected model is unavailable or the Gemini website protocol changed.": "Gemini Web: O modelo selecionado não está disponível ou o protocolo web do Gemini foi alterado.",
+ "Gemini Web: Gemini temporarily blocked requests from this network. Try again later.": "Gemini Web: O Gemini bloqueou temporariamente solicitações desta rede. Tente novamente mais tarde.",
+ "Gemini Web: This conversation can no longer be continued. Start a new conversation.": "Gemini Web: Esta conversa não pode mais ser continuada. Inicie uma nova conversa.",
+ "Gemini Web: This conversation has no stored Gemini model. Start a new conversation.": "Gemini Web: Esta conversa não tem um modelo Gemini salvo. Inicie uma nova conversa.",
+ "Gemini Web: The previous Gemini request may have changed the remote conversation. Start a new ChatGPTBox conversation.": "Gemini Web: A solicitação anterior ao Gemini pode ter alterado a conversa remota. Inicie uma nova conversa do ChatGPTBox.",
"This provider is still used by other API modes or saved conversations": "Este provedor ainda está sendo usado por outros modos de API ou conversas salvas",
"This API key is set on the selected custom mode. Editing it here will create a dedicated provider for that mode.": "Esta chave de API está definida no modo personalizado selecionado. Editá-la aqui vai criar um fornecedor dedicado para esse modo.",
"Use shared key": "Usar chave partilhada",
diff --git a/src/_locales/ru/main.json b/src/_locales/ru/main.json
index d857f3f62..00eab69d7 100644
--- a/src/_locales/ru/main.json
+++ b/src/_locales/ru/main.json
@@ -177,6 +177,49 @@
"Type": "Тип",
"Mode": "Режим",
"Custom": "Пользовательский",
+ "Extended thinking": "Расширенное мышление",
+ "A Gemini Web API mode with this model and thinking setting already exists.": "Режим API Gemini Web с этой моделью и настройкой рассуждений уже существует.",
+ "Gemini Web: Invalid response format. The website protocol may have changed.": "Gemini Web: Неверный формат ответа. Возможно, протокол сайта изменился.",
+ "Gemini Web: Invalid response frame length.": "Gemini Web: Неверная длина фрейма ответа.",
+ "Gemini Web: Truncated response frame.": "Gemini Web: Усечённый фрейм ответа.",
+ "Gemini Web: Invalid response envelope.": "Gemini Web: Неверная оболочка ответа.",
+ "Gemini Web: Invalid conversation identifier.": "Gemini Web: Неверный идентификатор диалога.",
+ "Gemini Web: Conversation identifiers changed during generation.": "Gemini Web: Идентификаторы диалога изменились во время генерации.",
+ "Gemini Web: The website rejected the request. Check Gemini in your browser.": "Gemini Web: Сайт отклонил запрос. Проверьте Gemini в вашем браузере.",
+ "Gemini Web: The website rejected the request ({{code}}). Check Gemini in your browser.": "Gemini Web: Сайт отклонил запрос ({{code}}). Проверьте Gemini в вашем браузере.",
+ "Gemini Web: Invalid response payload.": "Gemini Web: Неверные данные ответа.",
+ "Gemini Web: Invalid candidate identifier.": "Gemini Web: Неверный идентификатор кандидата.",
+ "Gemini Web: Candidate changed during generation.": "Gemini Web: Кандидат изменился во время генерации.",
+ "Gemini Web: Invalid text candidate.": "Gemini Web: Неверный текстовый кандидат.",
+ "Gemini Web: No text answer was received. Check Gemini in your browser.": "Gemini Web: Текстовый ответ не получен. Проверьте Gemini в вашем браузере.",
+ "Gemini Web: Could not confirm that the answer finished generating.": "Gemini Web: Не удалось подтвердить, что ответ полностью сформирован.",
+ "Gemini Web: The answer was interrupted before completion. Check Gemini before retrying.": "Gemini Web: Ответ был прерван до завершения. Проверьте Gemini перед повторной попыткой.",
+ "Gemini Web: Missing conversation identifiers.": "Gemini Web: Отсутствуют идентификаторы диалога.",
+ "Gemini Web: Invalid Google account route. Start a new conversation.": "Gemini Web: Неверный маршрут аккаунта Google. Начните новый диалог.",
+ "Gemini Web: Invalid website session data.": "Gemini Web: Неверные данные сессии сайта.",
+ "Gemini Web: HTTP {{status}}. Check your login and limits on Gemini.": "Gemini Web: HTTP {{status}}. Проверьте вход и лимиты в Gemini.",
+ "Gemini Web: Sign in to Gemini in this browser profile before trying again.": "Gemini Web: Войдите в Gemini в этом профиле браузера перед повторной попыткой.",
+ "Gemini Web: Empty website response.": "Gemini Web: Пустой ответ сайта.",
+ "Gemini Web: Website response is too large.": "Gemini Web: Ответ сайта слишком большой.",
+ "Gemini Web: The Google account route changed. Start a new conversation.": "Gemini Web: Маршрут аккаунта Google изменился. Начните новый диалог.",
+ "Gemini Web: The selected model is not available for this Google account.": "Gemini Web: Выбранная модель недоступна для этого аккаунта Google.",
+ "Gemini Web: Invalid Gemini Web model selection.": "Gemini Web: Неверный выбор модели Gemini Web.",
+ "Gemini Web: Gemini could not load the available models for this account.": "Gemini Web: Gemini не смог загрузить доступные модели для этого аккаунта.",
+ "Gemini Web: Invalid Gemini model discovery response.": "Gemini Web: Неверный ответ обнаружения моделей Gemini.",
+ "Gemini Web: Gemini returned no available model information.": "Gemini Web: Gemini не вернул информацию о доступных моделях.",
+ "Gemini Web: This Google account cannot select models ({{status}}).": "Gemini Web: Этот аккаунт Google не может выбирать модели ({{status}}).",
+ "Gemini Web: Invalid conversation state. Start a new conversation.": "Gemini Web: Неверное состояние диалога. Начните новый диалог.",
+ "Gemini Web: This conversation has no stored Google account route. Start a new conversation.": "Gemini Web: В этом диалоге нет сохранённого маршрута аккаунта Google. Начните новый диалог.",
+ "Gemini Web: Empty question.": "Gemini Web: Пустой вопрос.",
+ "Gemini Web: Request timed out. Check Gemini before retrying.": "Gemini Web: Время запроса истекло. Проверьте Gemini перед повторной попыткой.",
+ "Gemini Web: Gemini encountered a temporary generation error. Please retry.": "Gemini Web: В Gemini произошла временная ошибка генерации. Повторите попытку.",
+ "Gemini Web: Gemini usage limit reached for the selected model. Check Gemini before retrying.": "Gemini Web: Достигнут лимит использования выбранной модели. Проверьте Gemini перед повторной попыткой.",
+ "Gemini Web: The selected model does not match this conversation. Start a new conversation.": "Gemini Web: Выбранная модель не соответствует этой беседе. Начните новую беседу.",
+ "Gemini Web: The selected model is unavailable or the Gemini website protocol changed.": "Gemini Web: Выбранная модель недоступна или веб-протокол Gemini изменился.",
+ "Gemini Web: Gemini temporarily blocked requests from this network. Try again later.": "Gemini Web: Gemini временно заблокировал запросы из этой сети. Повторите попытку позже.",
+ "Gemini Web: This conversation can no longer be continued. Start a new conversation.": "Gemini Web: Эту беседу больше нельзя продолжить. Начните новую беседу.",
+ "Gemini Web: This conversation has no stored Gemini model. Start a new conversation.": "Gemini Web: Для этой беседы не сохранена модель Gemini. Начните новую беседу.",
+ "Gemini Web: The previous Gemini request may have changed the remote conversation. Start a new ChatGPTBox conversation.": "Gemini Web: Предыдущий запрос Gemini мог изменить удалённую беседу. Начните новую беседу ChatGPTBox.",
"This provider is still used by other API modes or saved conversations": "Этот провайдер всё ещё используется другими режимами API или сохранёнными диалогами",
"This API key is set on the selected custom mode. Editing it here will create a dedicated provider for that mode.": "Этот API-ключ задан в выбранном пользовательском режиме. Если изменить его здесь, будет создан отдельный провайдер для этого режима.",
"Use shared key": "Использовать общий ключ",
diff --git a/src/_locales/tr/main.json b/src/_locales/tr/main.json
index 1b2391cf4..34663e125 100644
--- a/src/_locales/tr/main.json
+++ b/src/_locales/tr/main.json
@@ -165,6 +165,49 @@
"Type": "Tür",
"Mode": "Mod",
"Custom": "Özel",
+ "Extended thinking": "Genişletilmiş düşünme",
+ "A Gemini Web API mode with this model and thinking setting already exists.": "Bu model ve düşünme ayarına sahip bir Gemini Web API modu zaten var.",
+ "Gemini Web: Invalid response format. The website protocol may have changed.": "Gemini Web: Geçersiz yanıt biçimi. Web sitesi protokolü değişmiş olabilir.",
+ "Gemini Web: Invalid response frame length.": "Gemini Web: Geçersiz yanıt çerçeve uzunluğu.",
+ "Gemini Web: Truncated response frame.": "Gemini Web: Kesilmiş yanıt çerçevesi.",
+ "Gemini Web: Invalid response envelope.": "Gemini Web: Geçersiz yanıt zarfı.",
+ "Gemini Web: Invalid conversation identifier.": "Gemini Web: Geçersiz konuşma tanımlayıcısı.",
+ "Gemini Web: Conversation identifiers changed during generation.": "Gemini Web: Oluşturma sırasında konuşma tanımlayıcıları değişti.",
+ "Gemini Web: The website rejected the request. Check Gemini in your browser.": "Gemini Web: Web sitesi isteği reddetti. Tarayıcınızda Gemini'yi kontrol edin.",
+ "Gemini Web: The website rejected the request ({{code}}). Check Gemini in your browser.": "Gemini Web: Web sitesi isteği reddetti ({{code}}). Tarayıcınızda Gemini'yi kontrol edin.",
+ "Gemini Web: Invalid response payload.": "Gemini Web: Geçersiz yanıt verisi.",
+ "Gemini Web: Invalid candidate identifier.": "Gemini Web: Geçersiz aday tanımlayıcısı.",
+ "Gemini Web: Candidate changed during generation.": "Gemini Web: Oluşturma sırasında aday değişti.",
+ "Gemini Web: Invalid text candidate.": "Gemini Web: Geçersiz metin adayı.",
+ "Gemini Web: No text answer was received. Check Gemini in your browser.": "Gemini Web: Metin yanıtı alınamadı. Tarayıcınızda Gemini'yi kontrol edin.",
+ "Gemini Web: Could not confirm that the answer finished generating.": "Gemini Web: Yanıtın oluşturulmasının tamamlandığı doğrulanamadı.",
+ "Gemini Web: The answer was interrupted before completion. Check Gemini before retrying.": "Gemini Web: Yanıt tamamlanmadan kesildi. Yeniden denemeden önce Gemini'yi kontrol edin.",
+ "Gemini Web: Missing conversation identifiers.": "Gemini Web: Konuşma tanımlayıcıları eksik.",
+ "Gemini Web: Invalid Google account route. Start a new conversation.": "Gemini Web: Geçersiz Google hesap yolu. Yeni bir konuşma başlatın.",
+ "Gemini Web: Invalid website session data.": "Gemini Web: Geçersiz web sitesi oturum verisi.",
+ "Gemini Web: HTTP {{status}}. Check your login and limits on Gemini.": "Gemini Web: HTTP {{status}}. Gemini'de girişinizi ve limitleri kontrol edin.",
+ "Gemini Web: Sign in to Gemini in this browser profile before trying again.": "Gemini Web: Yeniden denemeden önce bu tarayıcı profilinde Gemini'de oturum açın.",
+ "Gemini Web: Empty website response.": "Gemini Web: Boş web sitesi yanıtı.",
+ "Gemini Web: Website response is too large.": "Gemini Web: Web sitesi yanıtı çok büyük.",
+ "Gemini Web: The Google account route changed. Start a new conversation.": "Gemini Web: Google hesap yolu değişti. Yeni bir konuşma başlatın.",
+ "Gemini Web: The selected model is not available for this Google account.": "Gemini Web: Seçilen model bu Google hesabı için kullanılamıyor.",
+ "Gemini Web: Invalid Gemini Web model selection.": "Gemini Web: Geçersiz Gemini Web model seçimi.",
+ "Gemini Web: Gemini could not load the available models for this account.": "Gemini Web: Gemini bu hesap için kullanılabilir modelleri yükleyemedi.",
+ "Gemini Web: Invalid Gemini model discovery response.": "Gemini Web: Geçersiz Gemini model bulma yanıtı.",
+ "Gemini Web: Gemini returned no available model information.": "Gemini Web: Gemini kullanılabilir model bilgisi döndürmedi.",
+ "Gemini Web: This Google account cannot select models ({{status}}).": "Gemini Web: Bu Google hesabı model seçemiyor ({{status}}).",
+ "Gemini Web: Invalid conversation state. Start a new conversation.": "Gemini Web: Geçersiz konuşma durumu. Yeni bir konuşma başlatın.",
+ "Gemini Web: This conversation has no stored Google account route. Start a new conversation.": "Gemini Web: Bu konuşmanın kayıtlı Google hesap yolu yok. Yeni bir konuşma başlatın.",
+ "Gemini Web: Empty question.": "Gemini Web: Boş soru.",
+ "Gemini Web: Request timed out. Check Gemini before retrying.": "Gemini Web: İstek zaman aşımına uğradı. Yeniden denemeden önce Gemini'yi kontrol edin.",
+ "Gemini Web: Gemini encountered a temporary generation error. Please retry.": "Gemini Web: Gemini geçici bir oluşturma hatasıyla karşılaştı. Lütfen yeniden deneyin.",
+ "Gemini Web: Gemini usage limit reached for the selected model. Check Gemini before retrying.": "Gemini Web: Seçilen modelin kullanım sınırına ulaşıldı. Yeniden denemeden önce Gemini'yi kontrol edin.",
+ "Gemini Web: The selected model does not match this conversation. Start a new conversation.": "Gemini Web: Seçilen model bu konuşmayla eşleşmiyor. Yeni bir konuşma başlatın.",
+ "Gemini Web: The selected model is unavailable or the Gemini website protocol changed.": "Gemini Web: Seçilen model kullanılamıyor veya Gemini web protokolü değişti.",
+ "Gemini Web: Gemini temporarily blocked requests from this network. Try again later.": "Gemini Web: Gemini bu ağdan gelen istekleri geçici olarak engelledi. Daha sonra yeniden deneyin.",
+ "Gemini Web: This conversation can no longer be continued. Start a new conversation.": "Gemini Web: Bu konuşma artık sürdürülemiyor. Yeni bir konuşma başlatın.",
+ "Gemini Web: This conversation has no stored Gemini model. Start a new conversation.": "Gemini Web: Bu konuşma için kaydedilmiş bir Gemini modeli yok. Yeni bir konuşma başlatın.",
+ "Gemini Web: The previous Gemini request may have changed the remote conversation. Start a new ChatGPTBox conversation.": "Gemini Web: Önceki Gemini isteği uzak konuşmayı değiştirmiş olabilir. Yeni bir ChatGPTBox konuşması başlatın.",
"This provider is still used by other API modes or saved conversations": "Bu sağlayıcı hâlâ diğer API modları veya kaydedilmiş konuşmalar tarafından kullanılıyor",
"This API key is set on the selected custom mode. Editing it here will create a dedicated provider for that mode.": "Bu API anahtarı seçili özel modda ayarlanmış. Burada düzenlemek bu mod için özel bir sağlayıcı oluşturur.",
"Use shared key": "Paylaşılan anahtarı kullan",
diff --git a/src/_locales/zh-hans/main.json b/src/_locales/zh-hans/main.json
index cfad6d2d1..efbe4a76e 100644
--- a/src/_locales/zh-hans/main.json
+++ b/src/_locales/zh-hans/main.json
@@ -172,6 +172,49 @@
"Type": "类型",
"Mode": "模式",
"Custom": "自定义",
+ "Extended thinking": "延伸思考",
+ "A Gemini Web API mode with this model and thinking setting already exists.": "已存在使用此模型和思考设置的 Gemini 网页版 API 模式。",
+ "Gemini Web: Invalid response format. The website protocol may have changed.": "Google Gemini 网页版:响应格式无效,网站通信协议可能已变更。",
+ "Gemini Web: Invalid response frame length.": "Google Gemini 网页版:响应框架长度无效。",
+ "Gemini Web: Truncated response frame.": "Google Gemini 网页版:响应框架不完整。",
+ "Gemini Web: Invalid response envelope.": "Google Gemini 网页版:响应封装格式无效。",
+ "Gemini Web: Invalid conversation identifier.": "Google Gemini 网页版:对话标识符无效。",
+ "Gemini Web: Conversation identifiers changed during generation.": "Google Gemini 网页版:生成响应期间,对话标识符发生变更。",
+ "Gemini Web: The website rejected the request. Check Gemini in your browser.": "Google Gemini 网页版:网站拒绝此请求。请在浏览器中检查 Gemini。",
+ "Gemini Web: The website rejected the request ({{code}}). Check Gemini in your browser.": "Google Gemini 网页版:网站拒绝此请求({{code}})。请在浏览器中检查 Gemini。",
+ "Gemini Web: Invalid response payload.": "Google Gemini 网页版:响应内容格式无效。",
+ "Gemini Web: Invalid candidate identifier.": "Google Gemini 网页版:候选响应标识符无效。",
+ "Gemini Web: Candidate changed during generation.": "Google Gemini 网页版:生成响应期间,候选响应发生变更。",
+ "Gemini Web: Invalid text candidate.": "Google Gemini 网页版:文本候选响应格式无效。",
+ "Gemini Web: No text answer was received. Check Gemini in your browser.": "Google Gemini 网页版:未收到文本回答。请在浏览器中检查 Gemini。",
+ "Gemini Web: Could not confirm that the answer finished generating.": "Google Gemini 网页版:无法确认回答是否已完成生成。",
+ "Gemini Web: The answer was interrupted before completion. Check Gemini before retrying.": "Google Gemini 网页版:回答在完成前中断。重试前请先检查 Gemini。",
+ "Gemini Web: Missing conversation identifiers.": "Google Gemini 网页版:缺少对话标识符。",
+ "Gemini Web: Invalid Google account route. Start a new conversation.": "Google Gemini 网页版:Google 账户路径无效,请开始新对话。",
+ "Gemini Web: Invalid website session data.": "Google Gemini 网页版:网站会话数据无效。",
+ "Gemini Web: HTTP {{status}}. Check your login and limits on Gemini.": "Google Gemini 网页版:HTTP {{status}}。请确认 Gemini 的登录状态与使用限制。",
+ "Gemini Web: Sign in to Gemini in this browser profile before trying again.": "Google Gemini 网页版:请先在此浏览器配置文件登录 Gemini,再重试。",
+ "Gemini Web: Empty website response.": "Google Gemini 网页版:网站响应为空。",
+ "Gemini Web: Website response is too large.": "Google Gemini 网页版:网站响应过大。",
+ "Gemini Web: The Google account route changed. Start a new conversation.": "Google Gemini 网页版:Google 账户路径已变更,请开始新对话。",
+ "Gemini Web: The selected model is not available for this Google account.": "Google Gemini 网页版:此 Google 账户无法使用所选模型。",
+ "Gemini Web: Invalid Gemini Web model selection.": "Google Gemini 网页版:Gemini 网页版模型选择无效。",
+ "Gemini Web: Gemini could not load the available models for this account.": "Google Gemini 网页版:无法加载此账户可用的模型。",
+ "Gemini Web: Invalid Gemini model discovery response.": "Google Gemini 网页版:Gemini 模型信息响应无效。",
+ "Gemini Web: Gemini returned no available model information.": "Google Gemini 网页版:Gemini 未返回可用模型信息。",
+ "Gemini Web: This Google account cannot select models ({{status}}).": "Google Gemini 网页版:此 Google 账户无法选择模型({{status}})。",
+ "Gemini Web: Invalid conversation state. Start a new conversation.": "Google Gemini 网页版:对话状态无效,请开始新对话。",
+ "Gemini Web: This conversation has no stored Google account route. Start a new conversation.": "Google Gemini 网页版:此对话没有保存 Google 账户路径,请开始新对话。",
+ "Gemini Web: Empty question.": "Google Gemini 网页版:问题内容不可为空。",
+ "Gemini Web: Request timed out. Check Gemini before retrying.": "Google Gemini 网页版:请求超时。重试前请先检查 Gemini。",
+ "Gemini Web: Gemini encountered a temporary generation error. Please retry.": "Google Gemini 网页版:Gemini 遇到临时生成错误,请重试。",
+ "Gemini Web: Gemini usage limit reached for the selected model. Check Gemini before retrying.": "Google Gemini 网页版:所选模型已达到使用限制。请先在 Gemini 中检查使用限制,再重试。",
+ "Gemini Web: The selected model does not match this conversation. Start a new conversation.": "Google Gemini 网页版:所选模型与当前对话不匹配。请开始新对话。",
+ "Gemini Web: The selected model is unavailable or the Gemini website protocol changed.": "Google Gemini 网页版:所选模型当前不可用,或 Gemini 网页协议已发生变化。",
+ "Gemini Web: Gemini temporarily blocked requests from this network. Try again later.": "Google Gemini 网页版:Gemini 暂时阻止了来自此网络的请求,请稍后再试。",
+ "Gemini Web: This conversation can no longer be continued. Start a new conversation.": "Google Gemini 网页版:此对话已无法继续。请开始新对话。",
+ "Gemini Web: This conversation has no stored Gemini model. Start a new conversation.": "Google Gemini 网页版:此对话没有已保存的 Gemini 模型信息。请开始新对话。",
+ "Gemini Web: The previous Gemini request may have changed the remote conversation. Start a new ChatGPTBox conversation.": "Google Gemini 网页版:上一次 Gemini 请求可能已改变远端对话状态。请开始新的 ChatGPTBox 对话。",
"Kimi.Moonshot (Web, 100k)": "Kimi.Moonshot (网页版, 100k)",
"ChatGLM (GLM-4-Air, 128k)": "ChatGLM (GLM4Air, 性价比, 128k)",
"ChatGLM (GLM-4-0520, 128k)": "ChatGLM (GLM4-0520, 最智能, 128k)",
diff --git a/src/_locales/zh-hant/main.json b/src/_locales/zh-hant/main.json
index 3dd20a229..0f398f07d 100644
--- a/src/_locales/zh-hant/main.json
+++ b/src/_locales/zh-hant/main.json
@@ -172,6 +172,49 @@
"Type": "類型",
"Mode": "模式",
"Custom": "自訂",
+ "Extended thinking": "延伸思考",
+ "A Gemini Web API mode with this model and thinking setting already exists.": "已存在使用此模型與思考設定的 Google Gemini (網頁版) API 模式。",
+ "Gemini Web: Invalid response format. The website protocol may have changed.": "Google Gemini 網頁版:回應格式無效,網站通訊協定可能已變更。",
+ "Gemini Web: Invalid response frame length.": "Google Gemini 網頁版:回應框架長度無效。",
+ "Gemini Web: Truncated response frame.": "Google Gemini 網頁版:回應框架不完整。",
+ "Gemini Web: Invalid response envelope.": "Google Gemini 網頁版:回應封裝格式無效。",
+ "Gemini Web: Invalid conversation identifier.": "Google Gemini 網頁版:對話識別碼無效。",
+ "Gemini Web: Conversation identifiers changed during generation.": "Google Gemini 網頁版:產生回應期間,對話識別碼發生變更。",
+ "Gemini Web: The website rejected the request. Check Gemini in your browser.": "Google Gemini 網頁版:網站拒絕此要求。請在瀏覽器中檢查 Gemini。",
+ "Gemini Web: The website rejected the request ({{code}}). Check Gemini in your browser.": "Google Gemini 網頁版:網站拒絕此要求({{code}})。請在瀏覽器中檢查 Gemini。",
+ "Gemini Web: Invalid response payload.": "Google Gemini 網頁版:回應內容格式無效。",
+ "Gemini Web: Invalid candidate identifier.": "Google Gemini 網頁版:候選回應識別碼無效。",
+ "Gemini Web: Candidate changed during generation.": "Google Gemini 網頁版:產生回應期間,候選回應發生變更。",
+ "Gemini Web: Invalid text candidate.": "Google Gemini 網頁版:文字候選回應格式無效。",
+ "Gemini Web: No text answer was received. Check Gemini in your browser.": "Google Gemini 網頁版:未收到文字回答。請在瀏覽器中檢查 Gemini。",
+ "Gemini Web: Could not confirm that the answer finished generating.": "Google Gemini 網頁版:無法確認回答是否已完成產生。",
+ "Gemini Web: The answer was interrupted before completion. Check Gemini before retrying.": "Google Gemini 網頁版:回答在完成前中斷。重試前請先檢查 Gemini。",
+ "Gemini Web: Missing conversation identifiers.": "Google Gemini 網頁版:缺少對話識別碼。",
+ "Gemini Web: Invalid Google account route. Start a new conversation.": "Google Gemini 網頁版:Google 帳戶路徑無效,請開始新對話。",
+ "Gemini Web: Invalid website session data.": "Google Gemini 網頁版:網站工作階段資料無效。",
+ "Gemini Web: HTTP {{status}}. Check your login and limits on Gemini.": "Google Gemini 網頁版:HTTP {{status}}。請確認 Gemini 的登入狀態與使用限制。",
+ "Gemini Web: Sign in to Gemini in this browser profile before trying again.": "Google Gemini 網頁版:請先在此瀏覽器設定檔登入 Gemini,再重試。",
+ "Gemini Web: Empty website response.": "Google Gemini 網頁版:網站回應為空。",
+ "Gemini Web: Website response is too large.": "Google Gemini 網頁版:網站回應過大。",
+ "Gemini Web: The Google account route changed. Start a new conversation.": "Google Gemini 網頁版:Google 帳戶路徑已變更,請開始新對話。",
+ "Gemini Web: The selected model is not available for this Google account.": "Google Gemini 網頁版:此 Google 帳戶無法使用所選模型。",
+ "Gemini Web: Invalid Gemini Web model selection.": "Google Gemini 網頁版:Gemini 網頁版模型選擇無效。",
+ "Gemini Web: Gemini could not load the available models for this account.": "Google Gemini 網頁版:無法載入此帳戶可用的模型。",
+ "Gemini Web: Invalid Gemini model discovery response.": "Google Gemini 網頁版:Gemini 模型資訊回應無效。",
+ "Gemini Web: Gemini returned no available model information.": "Google Gemini 網頁版:Gemini 未回傳可用模型資訊。",
+ "Gemini Web: This Google account cannot select models ({{status}}).": "Google Gemini 網頁版:此 Google 帳戶無法選擇模型({{status}})。",
+ "Gemini Web: Invalid conversation state. Start a new conversation.": "Google Gemini 網頁版:對話狀態無效,請開始新對話。",
+ "Gemini Web: This conversation has no stored Google account route. Start a new conversation.": "Google Gemini 網頁版:此對話沒有儲存 Google 帳戶路徑,請開始新對話。",
+ "Gemini Web: Empty question.": "Google Gemini 網頁版:問題內容不可為空。",
+ "Gemini Web: Request timed out. Check Gemini before retrying.": "Google Gemini 網頁版:要求逾時。重試前請先檢查 Gemini。",
+ "Gemini Web: Gemini encountered a temporary generation error. Please retry.": "Google Gemini 網頁版:Gemini 發生暫時性的回答產生錯誤,請重試。",
+ "Gemini Web: Gemini usage limit reached for the selected model. Check Gemini before retrying.": "Google Gemini 網頁版:所選模型已達使用限制。請先在 Gemini 確認使用限制,再重試。",
+ "Gemini Web: The selected model does not match this conversation. Start a new conversation.": "Google Gemini 網頁版:所選模型與目前對話不相符。請開始新對話。",
+ "Gemini Web: The selected model is unavailable or the Gemini website protocol changed.": "Google Gemini 網頁版:所選模型目前無法使用,或 Gemini 網頁版通訊協定已變更。",
+ "Gemini Web: Gemini temporarily blocked requests from this network. Try again later.": "Google Gemini 網頁版:Gemini 暫時封鎖來自此網路的要求,請稍後再試。",
+ "Gemini Web: This conversation can no longer be continued. Start a new conversation.": "Google Gemini 網頁版:此對話已無法繼續。請開始新對話。",
+ "Gemini Web: This conversation has no stored Gemini model. Start a new conversation.": "Google Gemini 網頁版:此對話缺少已儲存的 Gemini 模型資訊。請開始新對話。",
+ "Gemini Web: The previous Gemini request may have changed the remote conversation. Start a new ChatGPTBox conversation.": "Google Gemini 網頁版:上一次 Gemini 要求可能已變更遠端對話狀態。請開始新的 ChatGPTBox 對話。",
"Crop Text to ensure the input tokens do not exceed the model's limit": "裁剪文本以確保輸入token不超過模型限制",
"Thinking Content": "思考內容",
"This provider is still used by other API modes or saved conversations": "此供應商仍被其他 API 模式或已儲存的對話使用中",
diff --git a/src/background/index.mjs b/src/background/index.mjs
index 79b4f0c0d..eebb0d249 100644
--- a/src/background/index.mjs
+++ b/src/background/index.mjs
@@ -38,7 +38,6 @@ import {
import '../_locales/i18n'
import { openUrl } from '../utils/open-url'
import {
- getBardCookies,
getBingAccessToken,
getChatGptAccessToken,
getClaudeSessionKey,
@@ -46,7 +45,7 @@ import {
} from '../services/wrappers.mjs'
import { refreshMenu } from './menus.mjs'
import { registerCommands } from './commands.mjs'
-import { generateAnswersWithBardWebApi } from '../services/apis/bard-web.mjs'
+import { generateAnswersWithGeminiWebApi } from '../services/apis/gemini-web.mjs'
import { generateAnswersWithClaudeWebApi } from '../services/apis/claude-web.mjs'
import { generateAnswersWithMoonshotWebApi } from '../services/apis/moonshot-web.mjs'
import { isUsingModelName } from '../utils/model-name-convert.mjs'
@@ -568,14 +567,14 @@ async function executeApi(
}
} else if (isUsingGeminiWebModel(session)) {
console.debug('[background] Using Gemini Web Model')
- const cookies = await getBardCookies()
if (!isLatestSessionRequest()) return
- await generateAnswersWithBardWebApi(
+ await generateAnswersWithGeminiWebApi(
port,
session.question,
session,
- cookies,
+ config,
isLatestSessionRequest,
+ connectionPort,
)
} else if (isUsingOpenAICompatibleApiSession(session)) {
console.debug('[background] Using OpenAI-compatible API provider')
diff --git a/src/components/ConversationCard/index.jsx b/src/components/ConversationCard/index.jsx
index 7458a0d89..b04825942 100644
--- a/src/components/ConversationCard/index.jsx
+++ b/src/components/ConversationCard/index.jsx
@@ -81,8 +81,12 @@ function ConversationCard(props) {
const retryRecordRef = useRef(null)
const retryGenerationIdRef = useRef(0)
const requestGenerationIdRef = useRef(0)
+ const runtimeGeminiContinuationInFlightRef = useRef(false)
const disposedRef = useRef(false)
const portRef = useRef(port)
+ const sessionRef = useRef(session)
+ const onUpdateRef = useRef(props.onUpdate)
+ const conversationItemDataRef = useRef([])
const foregroundMessageListeners = useRef([])
const foregroundPortsRef = useRef(new Set())
const completeDraggable = useMemo(() => !isSafari() && !isFirefox() && !isMobile(), [])
@@ -93,6 +97,9 @@ function ConversationCard(props) {
* @type {[ConversationItemData[], (conversationItemData: ConversationItemData[]) => void]}
*/
const [conversationItemData, setConversationItemData] = useState([])
+ sessionRef.current = session
+ onUpdateRef.current = props.onUpdate
+ conversationItemDataRef.current = conversationItemData
const config = useConfig()
const customOpenAIProviders = Array.isArray(config.customOpenAIProviders)
? config.customOpenAIProviders
@@ -112,8 +119,26 @@ function ConversationCard(props) {
? '-1'
: UNMATCHED_API_MODE_VALUE
+ const markRuntimeGeminiContinuationUnsafe = ({ updateState = true } = {}) => {
+ if (!runtimeGeminiContinuationInFlightRef.current) return
+ runtimeGeminiContinuationInFlightRef.current = false
+ const currentSession = sessionRef.current
+ const retryRecord = retryRecordRef.current
+ const restoredSession = retryRecord
+ ? finalizeInterruptedSession(currentSession, '', retryRecord)
+ : currentSession
+ const unsafeSession = {
+ ...restoredSession,
+ geminiWeb_conversationUnsafe: true,
+ }
+ sessionRef.current = unsafeSession
+ if (updateState) setSession(unsafeSession)
+ else onUpdateRef.current?.(portRef.current, unsafeSession, conversationItemDataRef.current)
+ }
+
const disposeOwnedTransports = () => {
if (disposedRef.current) return
+ markRuntimeGeminiContinuationUnsafe({ updateState: false })
disposedRef.current = true
requestGenerationIdRef.current += 1
retryGenerationIdRef.current += 1
@@ -222,6 +247,15 @@ function ConversationCard(props) {
if (isSupersededRequestMessage(msg, requestGenerationIdRef.current)) return
if (isSupersededGenerationMessage(msg, retryGenerationIdRef.current)) return
+ if (msg.geminiWebContinuationSubmitted === true) {
+ runtimeGeminiContinuationInFlightRef.current = true
+ }
+ if (msg.geminiWebConversationUnsafe === true) {
+ setSession((currentSession) => ({
+ ...currentSession,
+ geminiWeb_conversationUnsafe: true,
+ }))
+ }
if (msg.answer) {
partialAnswerRef.current = msg.answer
updateAnswer(msg.answer, false, 'answer')
@@ -230,6 +264,11 @@ function ConversationCard(props) {
setSession(msg.done ? { ...msg.session, isRetry: false } : msg.session)
}
if (msg.done) {
+ if (runtimeGeminiContinuationInFlightRef.current && !msg.session) {
+ markRuntimeGeminiContinuationUnsafe()
+ } else {
+ runtimeGeminiContinuationInFlightRef.current = false
+ }
const partialAnswer = partialAnswerRef.current
const retryRecord = retryRecordRef.current
const completionState = getInterruptedCompletionState(msg, partialAnswer, retryRecord)
@@ -245,6 +284,7 @@ function ConversationCard(props) {
setIsReady(true)
}
if (msg.error) {
+ runtimeGeminiContinuationInFlightRef.current = false
const retryRecord = retryRecordRef.current
setSession((currentSession) => finalizeInterruptedSession(currentSession, '', retryRecord))
switch (msg.error) {
@@ -409,14 +449,19 @@ function ConversationCard(props) {
}
}
} else {
- port.postMessage(
- createConversationPortMessage({
- session,
- stop,
- stopGenerationId,
- requestGenerationId,
- }),
- )
+ try {
+ port.postMessage(
+ createConversationPortMessage({
+ session,
+ stop,
+ stopGenerationId,
+ requestGenerationId,
+ }),
+ )
+ } catch (error) {
+ if (session) runtimeGeminiContinuationInFlightRef.current = false
+ throw error
+ }
}
}
@@ -424,9 +469,11 @@ function ConversationCard(props) {
const portListener = () => {
if (replacedPortRef.current === port) {
replacedPortRef.current = null
+ runtimeGeminiContinuationInFlightRef.current = false
return
}
if (disposedRef.current) return
+ markRuntimeGeminiContinuationUnsafe()
const nextPort = Browser.runtime.connect()
portRef.current = nextPort
setPort(nextPort)
@@ -605,6 +652,9 @@ function ConversationCard(props) {
aiName: apiMode
? getApiModeDisplayLabel(apiMode, t, customOpenAIProviders)
: modelNameToDesc(modelName, t, config.customModelName),
+ ...(runtimeGeminiContinuationInFlightRef.current
+ ? { geminiWeb_conversationUnsafe: true }
+ : {}),
}
if (config.autoRegenAfterSwitchModel && conversationItemData.length > 0)
getRetryFn(newSession)()
diff --git a/src/components/ConversationCard/session.mjs b/src/components/ConversationCard/session.mjs
index 40c60f166..d731dc805 100644
--- a/src/components/ConversationCard/session.mjs
+++ b/src/components/ConversationCard/session.mjs
@@ -1,19 +1,76 @@
import { pushRecord } from '../../services/apis/shared.mjs'
+function clearGeminiWebRetryConversation(session) {
+ if (!Object.hasOwn(session, 'geminiWeb_retryConversation')) return session
+ const updatedSession = { ...session }
+ delete updatedSession.geminiWeb_retryConversation
+ return updatedSession
+}
+
+function isGeminiWebSession(session) {
+ const modelName = typeof session?.modelName === 'string' ? session.modelName : ''
+ return (
+ session?.apiMode?.groupName === 'bardWebModelKeys' ||
+ modelName === 'bardWebFree' ||
+ modelName.startsWith('bardWebFree-')
+ )
+}
+
+function getGeminiWebRequestConversation(session) {
+ if (Object.hasOwn(session ?? {}, 'geminiWeb_retryConversation')) {
+ return session.geminiWeb_retryConversation
+ }
+ return session?.geminiWeb_conversation ?? session?.bard_conversationObj ?? {}
+}
+
+export function hasGeminiWebRemoteContinuation(session) {
+ if (!isGeminiWebSession(session)) return false
+ const conversation = getGeminiWebRequestConversation(session)
+ if (!conversation || typeof conversation !== 'object' || Array.isArray(conversation)) return false
+ const nonempty = (value) => value != null && value !== ''
+ return (
+ ['c', 'r', 'rc'].some((key) => nonempty(conversation[key])) ||
+ (Array.isArray(conversation.metadata) && conversation.metadata.some(nonempty))
+ )
+}
+
+function getGeminiWebRetryConversation(session, conversationRecords) {
+ const removedRecordIndex = conversationRecords.length
+ const lastGeminiRecordIndex = Number.isInteger(session.geminiWeb_lastRecordIndex)
+ ? session.geminiWeb_lastRecordIndex
+ : null
+ const hasPreviousConversation = Object.hasOwn(session, 'geminiWeb_previousConversation')
+
+ if (lastGeminiRecordIndex === removedRecordIndex) {
+ return hasPreviousConversation ? session.geminiWeb_previousConversation : null
+ }
+ if (lastGeminiRecordIndex !== null && lastGeminiRecordIndex < removedRecordIndex) {
+ if (session.geminiWeb_conversationUnsafe === true) return null
+ return session.geminiWeb_conversation ?? session.bard_conversationObj ?? {}
+ }
+ if (
+ lastGeminiRecordIndex === null &&
+ (hasPreviousConversation || session.geminiWeb_conversation || session.bard_conversationObj)
+ ) {
+ return null
+ }
+ return {}
+}
+
export function finalizeInterruptedSession(session, answer, retryRecord = null) {
if (!answer) {
- if (!session.isRetry && !retryRecord) return session
+ if (!session.isRetry && !retryRecord) return clearGeminiWebRetryConversation(session)
const lastRecord = session.conversationRecords.at(-1)
const shouldRestoreRetryRecord =
retryRecord &&
(lastRecord?.question !== retryRecord.question || lastRecord?.answer !== retryRecord.answer)
- return {
+ return clearGeminiWebRetryConversation({
...session,
conversationRecords: shouldRestoreRetryRecord
? [...session.conversationRecords, { ...retryRecord }]
: session.conversationRecords,
isRetry: false,
- }
+ })
}
const updatedSession = {
...session,
@@ -21,7 +78,7 @@ export function finalizeInterruptedSession(session, answer, retryRecord = null)
}
pushRecord(updatedSession, session.question, answer)
updatedSession.isRetry = false
- return updatedSession
+ return clearGeminiWebRetryConversation(updatedSession)
}
export function isSupersededGenerationMessage(message, latestSupersededGenerationId) {
@@ -53,11 +110,19 @@ export function createConversationPortMessage({
}
export function createRetrySession(session, conversationRecords, retryRecord) {
- return {
+ const retrySession = {
...session,
conversationRecords,
isRetry: retryRecord === null,
}
+ delete retrySession.geminiWeb_retryConversation
+ if (retryRecord !== null && isGeminiWebSession(session)) {
+ retrySession.geminiWeb_retryConversation = getGeminiWebRetryConversation(
+ session,
+ conversationRecords,
+ )
+ }
+ return retrySession
}
export function getCompletedAnswerUpdate(restoredRetryAnswer) {
diff --git a/src/config/index.mjs b/src/config/index.mjs
index 0a043c38c..01ab2eed8 100644
--- a/src/config/index.mjs
+++ b/src/config/index.mjs
@@ -864,6 +864,8 @@ export const defaultConfig = {
customChatGptWebApiPath: '/backend-api/conversation',
customOpenAiApiUrl: 'https://api.openai.com',
customAnthropicApiUrl: 'https://api.anthropic.com',
+ geminiWebModel: 'flash',
+ geminiWebExtendedThinking: false,
disableWebModeHistory: true,
hideContextMenu: false,
cropText: true,
diff --git a/src/pages/IndependentPanel/App.jsx b/src/pages/IndependentPanel/App.jsx
index 5552b6106..529e7dd8a 100644
--- a/src/pages/IndependentPanel/App.jsx
+++ b/src/pages/IndependentPanel/App.jsx
@@ -172,9 +172,10 @@ function App() {
pageMode={true}
onUpdate={(port, session, cData) => {
currentPort.current = port
- if (cData.length > 0 && cData[cData.length - 1].done) {
+ const completed = cData.length > 0 && cData[cData.length - 1].done
+ if (completed || session.geminiWeb_conversationUnsafe === true) {
updateSession(session).then(setSessions)
- setCurrentSession(session)
+ if (completed) setCurrentSession(session)
}
}}
/>
diff --git a/src/popup/api-mode-config-utils.mjs b/src/popup/api-mode-config-utils.mjs
index 2bfeae273..e700238a5 100644
--- a/src/popup/api-mode-config-utils.mjs
+++ b/src/popup/api-mode-config-utils.mjs
@@ -2,6 +2,8 @@ import { defaultApiModeIds } from '../config/index.mjs'
import { canonicalizeModelKeyArray } from '../config/model-key-migrations.mjs'
import { isApiModeSelected } from '../utils/model-name-convert.mjs'
+const GEMINI_WEB_DEFAULT_MODEL = 'bardWebFree'
+
export const API_MODE_LIST_CONFIG_KEYS = [
'activeApiModes',
'customApiModes',
@@ -9,9 +11,13 @@ export const API_MODE_LIST_CONFIG_KEYS = [
]
export function buildApiModeListConfigUpdate(config, nextApiModes, { selectionPatch = {} } = {}) {
+ const implicitDefaultIds = Object.hasOwn(config ?? {}, 'geminiWebModel')
+ ? [GEMINI_WEB_DEFAULT_MODEL]
+ : []
const knownApiModeDefaultIds = canonicalizeModelKeyArray([
...(Array.isArray(config?.knownApiModeDefaultIds) ? config.knownApiModeDefaultIds : []),
...defaultApiModeIds,
+ ...implicitDefaultIds,
])
return {
diff --git a/src/popup/sections/ApiModes.jsx b/src/popup/sections/ApiModes.jsx
index 5f39e0fa0..996deb0da 100644
--- a/src/popup/sections/ApiModes.jsx
+++ b/src/popup/sections/ApiModes.jsx
@@ -5,6 +5,12 @@ import { getApiModesFromConfig, isApiModeSelected, modelNameToDesc } from '../..
import { PencilIcon, TrashIcon } from '@primer/octicons-react'
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'
import { AlwaysCustomGroups, ModelGroups } from '../../config/index.mjs'
+import {
+ GEMINI_WEB_MODELS,
+ getGeminiWebModelLabel,
+ hasDuplicateGeminiWebPreset,
+ resolveGeminiWebPreset,
+} from '../../utils/gemini-web-preset.mjs'
import {
buildApiModeListConfigUpdate,
getSelectionPatchWhenApiModeDisabled,
@@ -50,6 +56,8 @@ ApiModes.propTypes = {
}
const LEGACY_CUSTOM_PROVIDER_ID = 'legacy-custom-default'
+const GEMINI_WEB_GROUP = 'bardWebModelKeys'
+const GEMINI_WEB_ITEM = 'bardWebFree'
const defaultApiMode = {
groupName: 'chatgptWebModelKeys',
@@ -72,6 +80,34 @@ const defaultProviderDraftValidation = {
apiUrl: false,
}
+function withGeminiWebPreset(
+ apiMode,
+ model,
+ extendedThinking,
+ extendedThinkingLabel = 'Extended thinking',
+) {
+ const normalizedModel = GEMINI_WEB_MODELS.includes(model) ? model : 'flash'
+ const useExtendedThinking =
+ !['auto', 'thinking'].includes(normalizedModel) && extendedThinking === true
+ const modelLabel = getGeminiWebModelLabel(normalizedModel)
+ return {
+ ...apiMode,
+ groupName: GEMINI_WEB_GROUP,
+ itemName: GEMINI_WEB_ITEM,
+ isCustom: true,
+ customName: useExtendedThinking ? `${modelLabel} + ${extendedThinkingLabel}` : modelLabel,
+ geminiWebModel: normalizedModel,
+ geminiWebExtendedThinking: useExtendedThinking,
+ }
+}
+
+function clearGeminiWebPreset(apiMode) {
+ const nextApiMode = { ...apiMode }
+ delete nextApiMode.geminiWebModel
+ delete nextApiMode.geminiWebExtendedThinking
+ return nextApiMode
+}
+
export function ApiModes({ config, updateConfig }) {
const { t } = useTranslation()
const [editing, setEditing] = useState(false)
@@ -93,6 +129,7 @@ export function ApiModes({ config, updateConfig }) {
defaultProviderDraftValidation,
)
const [providerSelectionValidation, setProviderSelectionValidation] = useState(false)
+ const [geminiPresetValidation, setGeminiPresetValidation] = useState('')
const providerNameInputRef = useRef(null)
const providerBaseUrlInputRef = useRef(null)
const providerSelectorRef = useRef(null)
@@ -141,6 +178,8 @@ export function ApiModes({ config, updateConfig }) {
}, [])
const shouldEditProvider = editingApiMode.groupName === 'customApiModelKeys'
+ const isEditingGeminiWeb = editingApiMode.groupName === GEMINI_WEB_GROUP
+ const geminiWebPreset = resolveGeminiWebPreset(editingApiMode, config)
const effectiveProviders = useMemo(
() =>
applyPendingProviderChanges(
@@ -390,6 +429,29 @@ export function ApiModes({ config, updateConfig }) {
const previousProviderId =
editingIndex === -1 ? '' : apiModes[editingIndex]?.providerId || LEGACY_CUSTOM_PROVIDER_ID
+ if (nextApiMode.groupName === GEMINI_WEB_GROUP) {
+ const preset = resolveGeminiWebPreset(nextApiMode, config)
+ if (preset.source === 'invalid') {
+ setGeminiPresetValidation('invalid')
+ return
+ }
+ nextApiMode = withGeminiWebPreset(
+ nextApiMode,
+ preset.model,
+ preset.extendedThinking,
+ t('Extended thinking'),
+ )
+ // Existing duplicate rows must be resolved too; saving them would keep selection ambiguous.
+ if (hasDuplicateGeminiWebPreset(apiModes, nextApiMode, editingIndex, config)) {
+ setGeminiPresetValidation('duplicate')
+ return
+ }
+ setGeminiPresetValidation('')
+ } else {
+ nextApiMode = clearGeminiWebPreset(nextApiMode)
+ setGeminiPresetValidation('')
+ }
+
if (shouldEditProvider) {
const selectedProviderId =
providerSelector === LEGACY_CUSTOM_PROVIDER_ID
@@ -427,6 +489,7 @@ export function ApiModes({ config, updateConfig }) {
onClick={(e) => {
e.preventDefault()
setEditing(false)
+ setGeminiPresetValidation('')
clearPendingProviderChanges()
closeProviderEditor()
}}
@@ -441,17 +504,31 @@ export function ApiModes({ config, updateConfig }) {
value={editingApiMode.groupName}
onChange={(e) => {
const groupName = e.target.value
+ setGeminiPresetValidation('')
let itemName = ModelGroups[groupName].value[0]
- const isCustom =
+ let isCustom =
editingApiMode.itemName === 'custom' && !AlwaysCustomGroups.includes(groupName)
- if (isCustom) itemName = 'custom'
+ let nextApiMode = { ...editingApiMode, groupName }
+ if (groupName === GEMINI_WEB_GROUP) {
+ nextApiMode = withGeminiWebPreset(nextApiMode, 'flash', false, t('Extended thinking'))
+ itemName = GEMINI_WEB_ITEM
+ isCustom = true
+ } else {
+ if (isCustom) itemName = 'custom'
+ nextApiMode = clearGeminiWebPreset({
+ ...nextApiMode,
+ itemName,
+ isCustom,
+ customName: isCustom ? nextApiMode.customName : '',
+ })
+ }
const providerId = resolveEditingProviderIdForGroupChange(
groupName,
editingApiMode.providerId,
LEGACY_CUSTOM_PROVIDER_ID,
)
setProviderSelectionValidation(false)
- setEditingApiMode({ ...editingApiMode, groupName, itemName, isCustom, providerId })
+ setEditingApiMode({ ...nextApiMode, providerId })
if (groupName === 'customApiModelKeys') {
setProviderSelector(providerId)
} else {
@@ -462,39 +539,103 @@ export function ApiModes({ config, updateConfig }) {
>
{Object.entries(ModelGroups).map(([groupName, { desc }]) => (
))}
-
+ {t(
+ geminiPresetValidation === 'duplicate'
+ ? 'A Gemini Web API mode with this model and thinking setting already exists.'
+ : 'Gemini Web: Invalid Gemini Web model selection.',
+ )}
+