docs(privacy): align Zoo Code observability retention with website policy#346
docs(privacy): align Zoo Code observability retention with website policy#346JamesRobert20 wants to merge 20 commits into
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a new "zoo-gateway" provider end-to-end (types, provider module, fetchers, handler, API wiring), updates model-cache behavior for auth-scoped models, extends webview/settings UI and validation, propagates Zoo auth tokens to all provider instances, expands telemetry to all authenticated users, updates PRIVACY.md, adds i18n keys and tests, and revises Vite build config. ChangesZoo Gateway + Telemetry
Estimated code review effort: 🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts
|
Co-authored-by: Cursor <cursoragent@cursor.com>
… fetch - Stop reassigning RouterProvider.client; thread Zoo enrichment headers through openAiHeaders so a single OpenAI client is used. - Replace npm_package_version (never populated at extension runtime) with Package.version from the shared package shim. - Default the model list to [] on a structurally broken response so we log and recover instead of crashing on response.data.data being undefined. - Bypass inFlightRefresh de-duplication for zoo-gateway: a refresh triggered after sign-out/sign-in must not return the previous user's in-flight response. - Add fetcher unit tests covering auth header, timeout, error redaction, and bad-response handling. Co-authored-by: Cursor <cursoragent@cursor.com>
…RouterName stays exhaustive Co-authored-by: Cursor <cursoragent@cursor.com>
…terName exhaustiveness holds Co-authored-by: Cursor <cursoragent@cursor.com>
f0aa066 to
3251b6e
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Co-authored-by: Cursor <cursoragent@cursor.com>
Cover constructor auth guard, base URL resolution, streaming, task/mode headers, temperature, cache breakpoints, tool calls, and completePrompt. Co-authored-by: Cursor <cursoragent@cursor.com>
proyectoauraorg
left a comment
There was a problem hiding this comment.
Review: Privacy/Telemetry Alignment
Verdict: ✅ Approved
Verified
- ✅
zoo-telemetry.test.ts— 5 tests pass (including new 'all authenticated users' test) - ✅ Subscription check removal is correct — server-side gating at zoocode.dev
- ✅ PRIVACY.md matches the code changes (90-day retention, plan-gated dashboard)
- ✅ Net code reduction (-10 lines) — removes unnecessary complexity
Important
The old code sent telemetry only to users with active subscriptions. This PR removes that client-side gate, so all authenticated users (free and paid) will now send telemetry. This is correct IF the server enforces plan-gated dashboard visibility (7 days Free / 90 days Pro+).
Recommend confirming that zoocode.dev server-side retention and dashboard visibility policies are implemented before merging this PR.
Dependency
Independent of the Zoo Gateway stack. Can merge to main at any time.
3251b6e to
89559d5
Compare
There was a problem hiding this comment.
Actionable comments posted: 11
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
🟡 Minor comments (11)
webview-ui/src/i18n/locales/es/settings.json-455-455 (1)
455-455:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix garbled UTF-8 text in Spanish locale strings.
Line 455 and Line 871 contain mojibake, so these messages will display corrupted characters in the UI.
💡 Proposed fix
- "googleCloudCredentialsPathWarning": "Este campo espera el contenido JSON de un archivo de clave de cuenta de servicio, no una ruta. Si tienes una ruta, p├⌐gala en el campo <strong>Ruta del archivo de clave de Google Cloud</strong> a continuaci├│n, o borra este campo y utiliza la variable de entorno <code>GOOGLE_APPLICATION_CREDENTIALS</code>.", + "googleCloudCredentialsPathWarning": "Este campo espera el contenido JSON de un archivo de clave de cuenta de servicio, no una ruta. Si tienes una ruta, pégala en el campo <strong>Ruta del archivo de clave de Google Cloud</strong> a continuación, o borra este campo y utiliza la variable de entorno <code>GOOGLE_APPLICATION_CREDENTIALS</code>.", @@ - "automaticFetch": "La extensi├│n obtiene autom├íticamente la lista m├ís reciente de modelos disponibles en <serviceLink>{{serviceName}}</serviceLink>. Si no est├í seguro de qu├⌐ modelo elegir, Zoo Code funciona mejor con <defaultModelLink>{{defaultModelId}}</defaultModelLink>. Tambi├⌐n puede buscar \"free\" para opciones sin costo actualmente disponibles.", + "automaticFetch": "La extensión obtiene automáticamente la lista más reciente de modelos disponibles en <serviceLink>{{serviceName}}</serviceLink>. Si no está seguro de qué modelo elegir, Zoo Code funciona mejor con <defaultModelLink>{{defaultModelId}}</defaultModelLink>. También puede buscar \"free\" para opciones sin costo actualmente disponibles.",Also applies to: 871-871
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webview-ui/src/i18n/locales/es/settings.json` at line 455, The Spanish locale string under the key "googleCloudCredentialsPathWarning" contains mojibake (e.g., "p├⌐gala", "a continuaci├│n"); update that value to use proper UTF-8 accented characters (e.g., "pégala", "a continuación") and scan the same file for the other affected key around line 871 to fix similar garbled sequences so all Spanish strings are valid UTF-8.src/api/providers/fetchers/zoo-gateway.ts-68-77 (1)
68-77:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winSkip model discovery when there is no session token.
Line 59 states auth is required, but Lines 68-77 still issue a network call without credentials. That creates guaranteed failures and noisy logs for signed-out users.
💡 Proposed fix
- const sessionToken = options?.zooSessionToken || getCachedZooCodeToken() - const headers: Record<string, string> = {} - if (sessionToken) { - headers["Authorization"] = `Bearer ${sessionToken}` - } + const sessionToken = options?.zooSessionToken ?? getCachedZooCodeToken() + if (!sessionToken) { + return models + } + const headers: Record<string, string> = { + Authorization: `Bearer ${sessionToken}`, + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/api/providers/fetchers/zoo-gateway.ts` around lines 68 - 77, The code issues an axios.get to `${baseURL}/models` even when no session token is available (sessionToken from options?.zooSessionToken || getCachedZooCodeToken), causing needless failed requests; update the logic to short-circuit before the network call when sessionToken is falsy (e.g., return an empty models list or null from the enclosing function), so do not call axios.get or use MODEL_DISCOVERY_TIMEOUT_MS without credentials—use the sessionToken variable and the axios.get call sites as the anchors to implement the early return.webview-ui/src/i18n/locales/de/settings.json-455-455 (1)
455-455:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix the mojibake in these German strings.
Both translated values are corrupted, so
googleCloudCredentialsPathWarningandmodelPicker.automaticFetchwill render as unreadable text in the settings UI.Also applies to: 871-871
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webview-ui/src/i18n/locales/de/settings.json` at line 455, The German strings contain mojibake where umlauts were corrupted; update the values for the keys googleCloudCredentialsPathWarning and modelPicker.automaticFetch in the locales file to use the correct German characters (e.g., "Schlüssel" and "Schlüsseldateipfad") so the messages read correctly—specifically replace "Schl├╝ssel" and "Schl├╝sseldateipfad" with "Schlüssel" and "Schlüsseldateipfad" and ensure the rest of the punctuation/HTML/templating (like <strong> and <code>) remains unchanged.webview-ui/src/i18n/locales/tr/settings.json-455-455 (1)
455-455:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix the mojibake in these Turkish strings.
googleCloudCredentialsPathWarningandmodelPicker.automaticFetchare corrupted here, so the translated settings copy will render unreadably.Also applies to: 871-871
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webview-ui/src/i18n/locales/tr/settings.json` at line 455, The Turkish strings for keys googleCloudCredentialsPathWarning and modelPicker.automaticFetch contain mojibake (corrupted characters); open the localization entries for these keys, replace the corrupted characters with the correct Turkish characters/words (e.g., restore characters like ı, ş, ç, ğ, ö, ü) so the sentences read naturally, ensure the file is saved in UTF-8 without BOM, and also fix the identical corrupted instance noted around the other occurrence (modelPicker.automaticFetch) so both entries render correctly.webview-ui/src/i18n/locales/zh-TW/settings.json-465-465 (1)
465-465:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix the mojibake in these Traditional Chinese strings.
Both values are corrupted, so
googleCloudCredentialsPathWarningandmodelPicker.automaticFetchwill show unreadable text in the UI.Also applies to: 881-881
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webview-ui/src/i18n/locales/zh-TW/settings.json` at line 465, The Traditional Chinese strings for the keys googleCloudCredentialsPathWarning and modelPicker.automaticFetch are corrupted (mojibake); locate the JSON entries for "googleCloudCredentialsPathWarning" and "modelPicker.automaticFetch" and replace the garbled text with correct Traditional Chinese translations, preserving any inline HTML tags like <strong> and <code> and ensuring the meaning about setting GOOGLE_APPLICATION_CREDENTIALS and automatic model fetching remains accurate; also fix the duplicate occurrence noted (the other affected entry around the second mention) so both occurrences show readable Traditional Chinese.webview-ui/src/i18n/locales/pt-BR/settings.json-455-455 (1)
455-455:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix mojibake in Portuguese translations.
These strings are UTF-8 corrupted and will render broken text in UI.
💡 Suggested fix
- "googleCloudCredentialsPathWarning": "Este campo espera o conte├║do JSON de um arquivo de chave de conta de servi├ºo, n├úo um caminho. Se voc├¬ tiver um caminho, cole-o no campo <strong>Caminho do Arquivo de Chave Google Cloud</strong> abaixo, ou limpe este campo e use a vari├ível de ambiente <code>GOOGLE_APPLICATION_CREDENTIALS</code>.", + "googleCloudCredentialsPathWarning": "Este campo espera o conteúdo JSON de um arquivo de chave de conta de serviço, não um caminho. Se você tiver um caminho, cole-o no campo <strong>Caminho do Arquivo de Chave Google Cloud</strong> abaixo, ou limpe este campo e use a variável de ambiente <code>GOOGLE_APPLICATION_CREDENTIALS</code>.", @@ - "automaticFetch": "A extens├úo busca automaticamente a lista mais recente de modelos dispon├¡veis em <serviceLink>{{serviceName}}</serviceLink>. Se voc├¬ n├úo tem certeza sobre qual modelo escolher, o Zoo Code funciona melhor com <defaultModelLink>{{defaultModelId}}</defaultModelLink>. Voc├¬ tamb├⌐m pode pesquisar por \"free\" para encontrar op├º├╡es gratuitas atualmente dispon├¡veis.", + "automaticFetch": "A extensão busca automaticamente a lista mais recente de modelos disponíveis em <serviceLink>{{serviceName}}</serviceLink>. Se você não tem certeza sobre qual modelo escolher, o Zoo Code funciona melhor com <defaultModelLink>{{defaultModelId}}</defaultModelLink>. Você também pode pesquisar por \"free\" para encontrar opções gratuitas atualmente disponíveis.",Also applies to: 871-871
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webview-ui/src/i18n/locales/pt-BR/settings.json` at line 455, The Portuguese translation for the key "googleCloudCredentialsPathWarning" (and the other affected key around the same area) contains mojibake (UTF-8 corruption) and must be replaced with correctly encoded UTF-8 text; locate the "googleCloudCredentialsPathWarning" entry in the pt-BR locale and update the string to use proper Portuguese characters (e.g., "conteúdo", "conta de serviço", "não", "você", "variável de ambiente", "Caminho do Arquivo de Chave Google Cloud") so the UI renders correctly; ensure the same corrections are applied to the other corrupted pt-BR string referenced in the review.webview-ui/src/i18n/locales/it/settings.json-871-871 (1)
871-871:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix corrupted UTF-8 in Italian
modelPicker.automaticFetch.The string includes mojibake (
pi├╣) and will display incorrectly.💡 Suggested fix
- "automaticFetch": "L'estensione recupera automaticamente l'elenco pi├╣ recente dei modelli disponibili su <serviceLink>{{serviceName}}</serviceLink>. Se non sei sicuro di quale modello scegliere, Zoo Code funziona meglio con <defaultModelLink>{{defaultModelId}}</defaultModelLink>. Puoi anche cercare \"free\" per opzioni gratuite attualmente disponibili.", + "automaticFetch": "L'estensione recupera automaticamente l'elenco più recente dei modelli disponibili su <serviceLink>{{serviceName}}</serviceLink>. Se non sei sicuro di quale modello scegliere, Zoo Code funziona meglio con <defaultModelLink>{{defaultModelId}}</defaultModelLink>. Puoi anche cercare \"free\" per opzioni gratuite attualmente disponibili.",🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webview-ui/src/i18n/locales/it/settings.json` at line 871, The value for the i18n key modelPicker.automaticFetch contains mojibake ("pi├╣") instead of the correct Italian character; update the string for modelPicker.automaticFetch to replace "pi├╣ recente" with "più recente" (keep the existing HTML-like links <serviceLink>{{serviceName}}</serviceLink> and <defaultModelLink>{{defaultModelId}}</defaultModelLink> and preserve any escaped quotes), ensuring the file is saved as UTF-8 so the "ù" character is stored correctly.src/core/webview/__tests__/ClineProvider.spec.ts-3760-3771 (1)
3760-3771:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAssert the state refresh you claim in the test.
This case only verifies the log path. A regression where
handleZooCodeCallback()stops callingpostStateToWebview()would still pass, despite the test name promising that behavior. Add an explicitexpect(provider.postStateToWebview).toHaveBeenCalled()or rename the test.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/core/webview/__tests__/ClineProvider.spec.ts` around lines 3760 - 3771, The test "logs and posts state when profile persistence fails" currently only asserts the log path; update the spec to also assert that provider.postStateToWebview was invoked after calling provider.handleZooCodeCallback("zoo_ext_token") (or alternatively rename the test to reflect it only verifies logging). Specifically, locate the test using provider.handleZooCodeCallback and add an expect(provider.postStateToWebview).toHaveBeenCalled() (or rename the it(...) description) so the test actually verifies the state-post behavior.webview-ui/src/i18n/locales/ca/settings.json-455-455 (1)
455-455:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix the encoding corruption in these translations.
These strings contain visible mojibake, so Catalan users will see broken copy in the settings UI. Please restore the intended text and save the file with the correct encoding.
Also applies to: 871-871
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webview-ui/src/i18n/locales/ca/settings.json` at line 455, The Catalan translation for the key "googleCloudCredentialsPathWarning" contains mojibake ("a continuaci├│")—replace it with the correct text ("a continuació") and verify the corresponding duplicate entry later in the same settings.json (the other occurrence flagged by the reviewer) is fixed the same way; finally re-save the file in UTF-8 (no BOM) to prevent encoding corruption going forward.webview-ui/src/i18n/locales/fr/settings.json-455-455 (1)
455-455:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winRestore these French strings before merge.
Both values contain mojibake, so the settings UI will show broken text instead of proper French copy. Reinsert the intended translation and save the file as UTF-8.
Also applies to: 871-871
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webview-ui/src/i18n/locales/fr/settings.json` at line 455, The JSON value for the "googleCloudCredentialsPathWarning" key contains mojibake (garbled characters); replace it with the correct French translation (use proper accents) and ensure the file is saved as UTF-8; also locate and fix the other occurrence noted (same mojibake at the other key around line 871) so both keys contain proper French strings with correct accents and encoding.webview-ui/src/i18n/locales/ja/settings.json-455-455 (1)
455-455:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix the mojibake in these localized strings.
Both entries are unreadable in the shipped UI because the text appears to have been saved with the wrong encoding. Restore the intended Japanese copy and re-save the file as UTF-8.
Also applies to: 871-871
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webview-ui/src/i18n/locales/ja/settings.json` at line 455, The value for the i18n key "googleCloudCredentialsPathWarning" contains mojibake (wrong encoding); open the locale file, replace the garbled string with the correct Japanese copy for that key (preserving the intended inline tokens like <strong>Google Cloud…</strong> and <code>GOOGLE_APPLICATION_CREDENTIALS</code>), ensure the file is saved as UTF-8 (preferably UTF-8 without BOM), and apply the same fix to the other corrupted localized entry in the same file that was flagged as also affected.
🧹 Nitpick comments (2)
webview-ui/src/components/settings/providers/__tests__/ZooGateway.spec.tsx (1)
150-152: ⚡ Quick winMake the non-call assertion wait past effect flush.
This can pass too early before async effects settle, so it may miss a late
setApiConfigurationFieldcall.Proposed test hardening
+import { act } from "`@/utils/test-utils`" ... - await waitFor(() => { - expect(setApiConfigurationField).not.toHaveBeenCalled() - }) + await act(async () => { + await Promise.resolve() + }) + expect(setApiConfigurationField).not.toHaveBeenCalled()🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webview-ui/src/components/settings/providers/__tests__/ZooGateway.spec.tsx` around lines 150 - 152, The non-call assertion for setApiConfigurationField in ZooGateway.spec.tsx can pass too early; wrap the expectation in waitFor that waits long enough for async effects (e.g., await waitFor(() => expect(setApiConfigurationField).not.toHaveBeenCalled(), { timeout: 1000 })) or explicitly flush pending promises before the assertion (e.g., await flushPromises(); expect(setApiConfigurationField).not.toHaveBeenCalled()); update the test to use one of these approaches targeting the waitFor/setApiConfigurationField usage so the assertion runs after effects settle.src/core/webview/__tests__/webviewMessageHandler.spec.ts (1)
397-433: ⚡ Quick winHarden shared mock cleanup to avoid test state bleed.
These tests mutate
mockClineProviderglobally and rely on inline cleanup. If a test fails early, state can leak into later tests. Move restoration toafterEach(ortry/finally) forproviderSettingsManager,upsertProviderProfile, and overriddencontextProxyfields.Suggested stabilization pattern
+let originalContextProxy: any + +beforeEach(() => { + originalContextProxy = mockClineProvider.contextProxy +}) + +afterEach(() => { + delete (mockClineProvider as any).providerSettingsManager + delete (mockClineProvider as any).upsertProviderProfile + ;(mockClineProvider as any).contextProxy = originalContextProxy +})Also applies to: 1163-1229
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/core/webview/__tests__/webviewMessageHandler.spec.ts` around lines 397 - 433, Tests mutate the shared mockClineProvider (providerSettingsManager, upsertProviderProfile, contextProxy) inline which can leak state if a test fails; instead, capture original values at test start and restore them in an afterEach hook (or wrap each test body in try/finally), e.g. save const origProviderSettings = (mockClineProvider as any).providerSettingsManager, origUpsert = (mockClineProvider as any).upsertProviderProfile, origContext = (mockClineProvider as any).contextProxy and restore them after the test; apply this stabilization for the tests that set providerSettingsManager, upsertProviderProfile, or override contextProxy (the block around webviewMessageHandler and the other similar test blocks).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/activate/handleUri.ts`:
- Around line 65-67: The loop over allInstances calls
instance.handleZooCodeCallback(token) directly, so one rejected call aborts the
whole loop; update the loop to call handleZooCodeCallback for each instance
inside a try/catch (e.g., within the for (const instance of allInstances)
block), catch and log the error (including instance identifier if available) and
continue to the next instance so one failure does not prevent other instances
from receiving the callback.
In `@src/api/providers/zoo-gateway.ts`:
- Around line 102-107: The code currently prefers options.zooSessionToken over
getCachedZooCodeToken(), which can keep using a stale profile token; change the
selection so the cached token is preferred (e.g., set sessionToken by calling
getCachedZooCodeToken() first and falling back to options.zooSessionToken) —
update the assignment around the sessionToken variable in the zoo-gateway.ts
handler where options.zooSessionToken and getCachedZooCodeToken() are used so
fresh cached tokens are used before the persisted profile token.
In `@src/core/webview/ClineProvider.ts`:
- Around line 873-916: ensureZooGatewayProfileSeeded currently only compares
profile.zooSessionToken to getCachedZooCodeToken(); also check that each
profile.zooGatewayBaseUrl equals the current getZooCodeBaseUrl() and treat any
mismatch as stale so seeding occurs. In the loop that inspects
zooGatewayProfiles (using providerSettingsManager.getProfile and the token
check), fetch the current base URL via getZooCodeBaseUrl(), compare it to
fullProfile.zooGatewayBaseUrl, and if different set allUpToDate = false, log a
descriptive message, and break so handleZooCodeCallback(token) will be invoked
to reseed both tokens and base URLs. Ensure references to
ensureZooGatewayProfileSeeded, getCachedZooCodeToken, getZooCodeBaseUrl,
providerSettingsManager.getProfile, and handleZooCodeCallback are used to locate
the changes.
In `@src/core/webview/webviewMessageHandler.ts`:
- Around line 948-968: The switch case for "requestRouterModels" contains
block-scoped declarations (e.g., const { apiConfiguration }, let
zooGatewayToken, const candidates) that must be isolated to avoid leaking across
cases; wrap the entire case "requestRouterModels" body in its own braces { ... }
so these let/const bindings are scoped to that case, ensuring code like
provider.providerSettingsManager.listConfig and related
zooGatewayToken/zooGatewayBaseUrl logic are enclosed and won't conflict with
other cases.
In `@webview-ui/src/i18n/locales/hi/settings.json`:
- Line 455: The string value for "googleCloudCredentialsPathWarning" (and the
other mojibake entry at line 871) contains garbled text; replace these mojibake
strings with proper Hindi translations while preserving inline HTML tags
(<strong>, <code>) and meaning about Google Cloud credentials and
GOOGLE_APPLICATION_CREDENTIALS, updating the JSON values for the keys (e.g.,
"googleCloudCredentialsPathWarning") so the help/setup content reads correctly
in Hindi.
In `@webview-ui/src/i18n/locales/ko/settings.json`:
- Line 455: Replace the garbled mojibake for the
"googleCloudCredentialsPathWarning" JSON value with the correct Korean
translation (restore the intended readable Korean copy), fix the other corrupted
string mentioned (line 871) the same way, and re-save the file as UTF-8 (no BOM)
so the encoding is preserved; locate these keys
("googleCloudCredentialsPathWarning" and the other corrupted key at line 871) in
webview-ui/src/i18n/locales/ko/settings.json and update their string values with
the proper Korean text.
In `@webview-ui/src/i18n/locales/pl/settings.json`:
- Line 455: The string value for "googleCloudCredentialsPathWarning" contains
mojibake (garbled Unicode) and should be replaced with correctly encoded Polish
text (use proper characters like ą,ę,ś,ł,ż,ó,ć,ń) and similarly fix the
corrupted message at the model-selection key on the other occurrence (line
~871); open the JSON entry for "googleCloudCredentialsPathWarning" and the
model-selection key, replace the garbled characters with the correct Polish
phrasing, and ensure the file is saved with UTF-8 encoding so the Polish
diacritics persist.
In `@webview-ui/src/i18n/locales/ru/settings.json`:
- Line 455: The JSON values for Russian locale contain encoding-corrupted text;
replace the corrupted value for the key "googleCloudCredentialsPathWarning" in
settings.json with a proper Russian translation and likewise locate and restore
the other corrupted Russian string near line 871 (search for non-UTF8/garbled
characters) so both warning/help messages are readable; ensure the replacements
are valid UTF-8, preserve existing HTML/inline code tags like <strong> and
<code> exactly, and run a quick JSON lint to confirm no syntax changes.
In `@webview-ui/src/i18n/locales/vi/settings.json`:
- Line 455: The string value for the locale key
"googleCloudCredentialsPathWarning" (and the other corrupted Vietnamese entry in
the same file) is mojibake; replace the corrupted text with the correct
Vietnamese translations, ensure the HTML (<strong>) and code (<code>) fragments
remain intact, save the file encoded as UTF-8 without BOM, and validate the JSON
(lint/parse) after the replacement so the locale renders correctly.
In `@webview-ui/src/i18n/locales/zh-CN/settings.json`:
- Line 455: Fix the mojibake in the Simplified Chinese locale by replacing the
corrupted string value for the key "googleCloudCredentialsPathWarning" (and the
other corrupted entry at the second occurrence referenced) with a proper
Simplified Chinese translation that preserves the embedded HTML and code tags
(<strong>...</strong> and <code>GOOGLE_APPLICATION_CREDENTIALS</code>); locate
the entries by the key "googleCloudCredentialsPathWarning" and the other
unreadable key near the same block, correct the text to clear, idiomatic Chinese
guidance about placing a Google Cloud service account JSON file and setting
GOOGLE_APPLICATION_CREDENTIALS, and keep surrounding JSON syntax and punctuation
unchanged.
In `@webview-ui/src/utils/validate.ts`:
- Around line 130-133: The validation for "zoo-gateway" currently accepts a user
if zooCodeIsAuthenticated is true even when apiConfiguration.zooSessionToken is
missing; change the condition in validate.ts (the "zoo-gateway" case) to require
the persisted token (apiConfiguration.zooSessionToken) be present before passing
validation and do not treat zooCodeIsAuthenticated as a substitute, or
alternatively add and check a seeding-complete flag (set by
ensureZooGatewayProfileSeeded) so validation only passes when the stored token
is present or seeding has finished; update the return logic that currently
references apiConfiguration.zooSessionToken and zooCodeIsAuthenticated
accordingly.
---
Minor comments:
In `@src/api/providers/fetchers/zoo-gateway.ts`:
- Around line 68-77: The code issues an axios.get to `${baseURL}/models` even
when no session token is available (sessionToken from options?.zooSessionToken
|| getCachedZooCodeToken), causing needless failed requests; update the logic to
short-circuit before the network call when sessionToken is falsy (e.g., return
an empty models list or null from the enclosing function), so do not call
axios.get or use MODEL_DISCOVERY_TIMEOUT_MS without credentials—use the
sessionToken variable and the axios.get call sites as the anchors to implement
the early return.
In `@src/core/webview/__tests__/ClineProvider.spec.ts`:
- Around line 3760-3771: The test "logs and posts state when profile persistence
fails" currently only asserts the log path; update the spec to also assert that
provider.postStateToWebview was invoked after calling
provider.handleZooCodeCallback("zoo_ext_token") (or alternatively rename the
test to reflect it only verifies logging). Specifically, locate the test using
provider.handleZooCodeCallback and add an
expect(provider.postStateToWebview).toHaveBeenCalled() (or rename the it(...)
description) so the test actually verifies the state-post behavior.
In `@webview-ui/src/i18n/locales/ca/settings.json`:
- Line 455: The Catalan translation for the key
"googleCloudCredentialsPathWarning" contains mojibake ("a continuaci├│")—replace
it with the correct text ("a continuació") and verify the corresponding
duplicate entry later in the same settings.json (the other occurrence flagged by
the reviewer) is fixed the same way; finally re-save the file in UTF-8 (no BOM)
to prevent encoding corruption going forward.
In `@webview-ui/src/i18n/locales/de/settings.json`:
- Line 455: The German strings contain mojibake where umlauts were corrupted;
update the values for the keys googleCloudCredentialsPathWarning and
modelPicker.automaticFetch in the locales file to use the correct German
characters (e.g., "Schlüssel" and "Schlüsseldateipfad") so the messages read
correctly—specifically replace "Schl├╝ssel" and "Schl├╝sseldateipfad" with
"Schlüssel" and "Schlüsseldateipfad" and ensure the rest of the
punctuation/HTML/templating (like <strong> and <code>) remains unchanged.
In `@webview-ui/src/i18n/locales/es/settings.json`:
- Line 455: The Spanish locale string under the key
"googleCloudCredentialsPathWarning" contains mojibake (e.g., "pégala", "a
continuaci├│n"); update that value to use proper UTF-8 accented characters
(e.g., "pégala", "a continuación") and scan the same file for the other affected
key around line 871 to fix similar garbled sequences so all Spanish strings are
valid UTF-8.
In `@webview-ui/src/i18n/locales/fr/settings.json`:
- Line 455: The JSON value for the "googleCloudCredentialsPathWarning" key
contains mojibake (garbled characters); replace it with the correct French
translation (use proper accents) and ensure the file is saved as UTF-8; also
locate and fix the other occurrence noted (same mojibake at the other key around
line 871) so both keys contain proper French strings with correct accents and
encoding.
In `@webview-ui/src/i18n/locales/it/settings.json`:
- Line 871: The value for the i18n key modelPicker.automaticFetch contains
mojibake ("pi├╣") instead of the correct Italian character; update the string
for modelPicker.automaticFetch to replace "pi├╣ recente" with "più recente"
(keep the existing HTML-like links <serviceLink>{{serviceName}}</serviceLink>
and <defaultModelLink>{{defaultModelId}}</defaultModelLink> and preserve any
escaped quotes), ensuring the file is saved as UTF-8 so the "ù" character is
stored correctly.
In `@webview-ui/src/i18n/locales/ja/settings.json`:
- Line 455: The value for the i18n key "googleCloudCredentialsPathWarning"
contains mojibake (wrong encoding); open the locale file, replace the garbled
string with the correct Japanese copy for that key (preserving the intended
inline tokens like <strong>Google Cloud…</strong> and
<code>GOOGLE_APPLICATION_CREDENTIALS</code>), ensure the file is saved as UTF-8
(preferably UTF-8 without BOM), and apply the same fix to the other corrupted
localized entry in the same file that was flagged as also affected.
In `@webview-ui/src/i18n/locales/pt-BR/settings.json`:
- Line 455: The Portuguese translation for the key
"googleCloudCredentialsPathWarning" (and the other affected key around the same
area) contains mojibake (UTF-8 corruption) and must be replaced with correctly
encoded UTF-8 text; locate the "googleCloudCredentialsPathWarning" entry in the
pt-BR locale and update the string to use proper Portuguese characters (e.g.,
"conteúdo", "conta de serviço", "não", "você", "variável de ambiente", "Caminho
do Arquivo de Chave Google Cloud") so the UI renders correctly; ensure the same
corrections are applied to the other corrupted pt-BR string referenced in the
review.
In `@webview-ui/src/i18n/locales/tr/settings.json`:
- Line 455: The Turkish strings for keys googleCloudCredentialsPathWarning and
modelPicker.automaticFetch contain mojibake (corrupted characters); open the
localization entries for these keys, replace the corrupted characters with the
correct Turkish characters/words (e.g., restore characters like ı, ş, ç, ğ, ö,
ü) so the sentences read naturally, ensure the file is saved in UTF-8 without
BOM, and also fix the identical corrupted instance noted around the other
occurrence (modelPicker.automaticFetch) so both entries render correctly.
In `@webview-ui/src/i18n/locales/zh-TW/settings.json`:
- Line 465: The Traditional Chinese strings for the keys
googleCloudCredentialsPathWarning and modelPicker.automaticFetch are corrupted
(mojibake); locate the JSON entries for "googleCloudCredentialsPathWarning" and
"modelPicker.automaticFetch" and replace the garbled text with correct
Traditional Chinese translations, preserving any inline HTML tags like <strong>
and <code> and ensuring the meaning about setting GOOGLE_APPLICATION_CREDENTIALS
and automatic model fetching remains accurate; also fix the duplicate occurrence
noted (the other affected entry around the second mention) so both occurrences
show readable Traditional Chinese.
---
Nitpick comments:
In `@src/core/webview/__tests__/webviewMessageHandler.spec.ts`:
- Around line 397-433: Tests mutate the shared mockClineProvider
(providerSettingsManager, upsertProviderProfile, contextProxy) inline which can
leak state if a test fails; instead, capture original values at test start and
restore them in an afterEach hook (or wrap each test body in try/finally), e.g.
save const origProviderSettings = (mockClineProvider as
any).providerSettingsManager, origUpsert = (mockClineProvider as
any).upsertProviderProfile, origContext = (mockClineProvider as
any).contextProxy and restore them after the test; apply this stabilization for
the tests that set providerSettingsManager, upsertProviderProfile, or override
contextProxy (the block around webviewMessageHandler and the other similar test
blocks).
In `@webview-ui/src/components/settings/providers/__tests__/ZooGateway.spec.tsx`:
- Around line 150-152: The non-call assertion for setApiConfigurationField in
ZooGateway.spec.tsx can pass too early; wrap the expectation in waitFor that
waits long enough for async effects (e.g., await waitFor(() =>
expect(setApiConfigurationField).not.toHaveBeenCalled(), { timeout: 1000 })) or
explicitly flush pending promises before the assertion (e.g., await
flushPromises(); expect(setApiConfigurationField).not.toHaveBeenCalled());
update the test to use one of these approaches targeting the
waitFor/setApiConfigurationField usage so the assertion runs after effects
settle.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 087f53ae-b7bd-4ddc-b44c-cb6d44c2080d
📒 Files selected for processing (50)
PRIVACY.mdpackages/types/src/provider-settings.tspackages/types/src/providers/index.tspackages/types/src/providers/zoo-gateway.tssrc/activate/__tests__/handleUri.spec.tssrc/activate/handleUri.tssrc/api/index.tssrc/api/providers/fetchers/__tests__/zoo-gateway.spec.tssrc/api/providers/fetchers/modelCache.tssrc/api/providers/fetchers/zoo-gateway.tssrc/api/providers/index.tssrc/api/providers/zoo-gateway.tssrc/core/webview/ClineProvider.tssrc/core/webview/__tests__/ClineProvider.spec.tssrc/core/webview/__tests__/webviewMessageHandler.spec.tssrc/core/webview/webviewMessageHandler.tssrc/i18n/locales/en/common.jsonsrc/services/__tests__/zoo-telemetry.test.tssrc/services/zoo-telemetry.tssrc/shared/api.tswebview-ui/src/components/settings/ApiOptions.tsxwebview-ui/src/components/settings/ModelPicker.tsxwebview-ui/src/components/settings/__tests__/ApiOptions.spec.tsxwebview-ui/src/components/settings/constants.tswebview-ui/src/components/settings/providers/ZooGateway.tsxwebview-ui/src/components/settings/providers/__tests__/ZooGateway.spec.tsxwebview-ui/src/components/settings/providers/index.tswebview-ui/src/components/ui/hooks/useSelectedModel.tswebview-ui/src/components/welcome/WelcomeViewProvider.tsxwebview-ui/src/i18n/locales/ca/settings.jsonwebview-ui/src/i18n/locales/de/settings.jsonwebview-ui/src/i18n/locales/en/settings.jsonwebview-ui/src/i18n/locales/es/settings.jsonwebview-ui/src/i18n/locales/fr/settings.jsonwebview-ui/src/i18n/locales/hi/settings.jsonwebview-ui/src/i18n/locales/id/settings.jsonwebview-ui/src/i18n/locales/it/settings.jsonwebview-ui/src/i18n/locales/ja/settings.jsonwebview-ui/src/i18n/locales/ko/settings.jsonwebview-ui/src/i18n/locales/nl/settings.jsonwebview-ui/src/i18n/locales/pl/settings.jsonwebview-ui/src/i18n/locales/pt-BR/settings.jsonwebview-ui/src/i18n/locales/ru/settings.jsonwebview-ui/src/i18n/locales/tr/settings.jsonwebview-ui/src/i18n/locales/vi/settings.jsonwebview-ui/src/i18n/locales/zh-CN/settings.jsonwebview-ui/src/i18n/locales/zh-TW/settings.jsonwebview-ui/src/utils/__tests__/validate.spec.tswebview-ui/src/utils/validate.tswebview-ui/vite.config.ts
✅ Files skipped from review due to trivial changes (6)
- webview-ui/src/components/settings/providers/index.ts
- webview-ui/src/components/settings/constants.ts
- webview-ui/src/utils/tests/validate.spec.ts
- webview-ui/src/i18n/locales/en/settings.json
- webview-ui/src/i18n/locales/nl/settings.json
- PRIVACY.md
🚧 Files skipped from review as they are similar to previous changes (1)
- src/services/tests/zoo-telemetry.test.ts
| for (const instance of allInstances) { | ||
| await instance.handleZooCodeCallback(token) | ||
| } |
There was a problem hiding this comment.
Isolate per-instance callback failures so one throw doesn’t block the rest.
A single rejected handleZooCodeCallback aborts the loop and leaves other active instances stale.
Proposed resilience fix
const allInstances = ClineProvider.getAllInstances()
for (const instance of allInstances) {
- await instance.handleZooCodeCallback(token)
+ try {
+ await instance.handleZooCodeCallback(token)
+ } catch (error) {
+ console.error("Failed to persist Zoo Code callback for one provider instance")
+ }
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/activate/handleUri.ts` around lines 65 - 67, The loop over allInstances
calls instance.handleZooCodeCallback(token) directly, so one rejected call
aborts the whole loop; update the loop to call handleZooCodeCallback for each
instance inside a try/catch (e.g., within the for (const instance of
allInstances) block), catch and log the error (including instance identifier if
available) and continue to the next instance so one failure does not prevent
other instances from receiving the callback.
| // Prefer the profile-persisted token; fall back to the secret-storage cache so | ||
| // requests work when the user is signed in but the profile hasn't been seeded yet | ||
| // (e.g. auth callback arrived before any webview instance was open). | ||
| const sessionToken = options.zooSessionToken || getCachedZooCodeToken() | ||
| if (!sessionToken) { | ||
| throw new Error("Zoo Gateway requires authentication. Please sign in to Zoo Code first.") |
There was a problem hiding this comment.
Prefer the cached Zoo Code token over the persisted profile token.
After re-auth or token rotation, options.zooSessionToken can be stale while getCachedZooCodeToken() already holds the fresh session. The current order keeps using the stale profile token, so the handler can stay stuck on repeated 401s until profile sync finishes successfully.
Suggested fix
- const sessionToken = options.zooSessionToken || getCachedZooCodeToken()
+ const sessionToken = getCachedZooCodeToken() || options.zooSessionToken📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Prefer the profile-persisted token; fall back to the secret-storage cache so | |
| // requests work when the user is signed in but the profile hasn't been seeded yet | |
| // (e.g. auth callback arrived before any webview instance was open). | |
| const sessionToken = options.zooSessionToken || getCachedZooCodeToken() | |
| if (!sessionToken) { | |
| throw new Error("Zoo Gateway requires authentication. Please sign in to Zoo Code first.") | |
| // Prefer the profile-persisted token; fall back to the secret-storage cache so | |
| // requests work when the user is signed in but the profile hasn't been seeded yet | |
| // (e.g. auth callback arrived before any webview instance was open). | |
| const sessionToken = getCachedZooCodeToken() || options.zooSessionToken | |
| if (!sessionToken) { | |
| throw new Error("Zoo Gateway requires authentication. Please sign in to Zoo Code first.") |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/api/providers/zoo-gateway.ts` around lines 102 - 107, The code currently
prefers options.zooSessionToken over getCachedZooCodeToken(), which can keep
using a stale profile token; change the selection so the cached token is
preferred (e.g., set sessionToken by calling getCachedZooCodeToken() first and
falling back to options.zooSessionToken) — update the assignment around the
sessionToken variable in the zoo-gateway.ts handler where
options.zooSessionToken and getCachedZooCodeToken() are used so fresh cached
tokens are used before the persisted profile token.
| private async ensureZooGatewayProfileSeeded(): Promise<void> { | ||
| const { getCachedZooCodeToken } = await import("../../services/zoo-code-auth") | ||
| const token = getCachedZooCodeToken() | ||
| if (!token) return | ||
|
|
||
| // Check ALL zoo-gateway profiles — only skip seeding if every profile has the current token. | ||
| // Using .find() would miss stale tokens in duplicate/renamed profiles since handleZooCodeCallback | ||
| // uses .filter() and updates all of them — the early-return guard must match. | ||
| const allProfiles = await this.providerSettingsManager.listConfig() | ||
| const zooGatewayProfiles = allProfiles.filter((p) => p.apiProvider === "zoo-gateway") | ||
|
|
||
| if (zooGatewayProfiles.length === 0) { | ||
| this.log("[ensureZooGatewayProfileSeeded] No zoo-gateway profile found, creating one") | ||
| } else { | ||
| let allUpToDate = true | ||
|
|
||
| for (const entry of zooGatewayProfiles) { | ||
| try { | ||
| const fullProfile = await this.providerSettingsManager.getProfile({ name: entry.name }) | ||
| if (fullProfile.zooSessionToken !== token) { | ||
| allUpToDate = false | ||
| this.log( | ||
| fullProfile.zooSessionToken | ||
| ? "[ensureZooGatewayProfileSeeded] Token mismatch (stale session?), updating with current token" | ||
| : "[ensureZooGatewayProfileSeeded] Existing zoo-gateway profile has no token, updating with cached token", | ||
| ) | ||
| break | ||
| } | ||
| } catch { | ||
| allUpToDate = false | ||
| this.log("[ensureZooGatewayProfileSeeded] Failed to read existing profile, will re-seed") | ||
| break | ||
| } | ||
| } | ||
|
|
||
| if (allUpToDate) { | ||
| // All profiles have the current token — nothing to do | ||
| return | ||
| } | ||
| } | ||
|
|
||
| // User has token but either no profile, some profiles without token, or stale tokens — seed all | ||
| await this.handleZooCodeCallback(token) | ||
| } |
There was a problem hiding this comment.
Also repair stale zooGatewayBaseUrl values here.
The early-return only verifies that each profile already has the cached token. If getZooCodeBaseUrl() changes between sessions, every profile can look "up to date" while still pointing at the old gateway host, so requests keep routing to the wrong environment until the user re-authenticates.
Suggested fix
private async ensureZooGatewayProfileSeeded(): Promise<void> {
- const { getCachedZooCodeToken } = await import("../../services/zoo-code-auth")
+ const { getCachedZooCodeToken, getZooCodeBaseUrl } = await import("../../services/zoo-code-auth")
const token = getCachedZooCodeToken()
if (!token) return
+ const derivedGatewayBaseUrl = `${getZooCodeBaseUrl()}/api/gateway/v1`
// Check ALL zoo-gateway profiles — only skip seeding if every profile has the current token.
// Using .find() would miss stale tokens in duplicate/renamed profiles since handleZooCodeCallback
// uses .filter() and updates all of them — the early-return guard must match.
const allProfiles = await this.providerSettingsManager.listConfig()
const zooGatewayProfiles = allProfiles.filter((p) => p.apiProvider === "zoo-gateway")
if (zooGatewayProfiles.length === 0) {
this.log("[ensureZooGatewayProfileSeeded] No zoo-gateway profile found, creating one")
} else {
let allUpToDate = true
for (const entry of zooGatewayProfiles) {
try {
const fullProfile = await this.providerSettingsManager.getProfile({ name: entry.name })
- if (fullProfile.zooSessionToken !== token) {
+ if (
+ fullProfile.zooSessionToken !== token ||
+ fullProfile.zooGatewayBaseUrl !== derivedGatewayBaseUrl
+ ) {
allUpToDate = false
- this.log(
- fullProfile.zooSessionToken
- ? "[ensureZooGatewayProfileSeeded] Token mismatch (stale session?), updating with current token"
- : "[ensureZooGatewayProfileSeeded] Existing zoo-gateway profile has no token, updating with cached token",
- )
+ this.log("[ensureZooGatewayProfileSeeded] Existing zoo-gateway profile is stale, updating")
break
}
} catch {
allUpToDate = false
this.log("[ensureZooGatewayProfileSeeded] Failed to read existing profile, will re-seed")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| private async ensureZooGatewayProfileSeeded(): Promise<void> { | |
| const { getCachedZooCodeToken } = await import("../../services/zoo-code-auth") | |
| const token = getCachedZooCodeToken() | |
| if (!token) return | |
| // Check ALL zoo-gateway profiles — only skip seeding if every profile has the current token. | |
| // Using .find() would miss stale tokens in duplicate/renamed profiles since handleZooCodeCallback | |
| // uses .filter() and updates all of them — the early-return guard must match. | |
| const allProfiles = await this.providerSettingsManager.listConfig() | |
| const zooGatewayProfiles = allProfiles.filter((p) => p.apiProvider === "zoo-gateway") | |
| if (zooGatewayProfiles.length === 0) { | |
| this.log("[ensureZooGatewayProfileSeeded] No zoo-gateway profile found, creating one") | |
| } else { | |
| let allUpToDate = true | |
| for (const entry of zooGatewayProfiles) { | |
| try { | |
| const fullProfile = await this.providerSettingsManager.getProfile({ name: entry.name }) | |
| if (fullProfile.zooSessionToken !== token) { | |
| allUpToDate = false | |
| this.log( | |
| fullProfile.zooSessionToken | |
| ? "[ensureZooGatewayProfileSeeded] Token mismatch (stale session?), updating with current token" | |
| : "[ensureZooGatewayProfileSeeded] Existing zoo-gateway profile has no token, updating with cached token", | |
| ) | |
| break | |
| } | |
| } catch { | |
| allUpToDate = false | |
| this.log("[ensureZooGatewayProfileSeeded] Failed to read existing profile, will re-seed") | |
| break | |
| } | |
| } | |
| if (allUpToDate) { | |
| // All profiles have the current token — nothing to do | |
| return | |
| } | |
| } | |
| // User has token but either no profile, some profiles without token, or stale tokens — seed all | |
| await this.handleZooCodeCallback(token) | |
| } | |
| private async ensureZooGatewayProfileSeeded(): Promise<void> { | |
| const { getCachedZooCodeToken, getZooCodeBaseUrl } = await import("../../services/zoo-code-auth") | |
| const token = getCachedZooCodeToken() | |
| if (!token) return | |
| const derivedGatewayBaseUrl = `${getZooCodeBaseUrl()}/api/gateway/v1` | |
| // Check ALL zoo-gateway profiles — only skip seeding if every profile has the current token. | |
| // Using .find() would miss stale tokens in duplicate/renamed profiles since handleZooCodeCallback | |
| // uses .filter() and updates all of them — the early-return guard must match. | |
| const allProfiles = await this.providerSettingsManager.listConfig() | |
| const zooGatewayProfiles = allProfiles.filter((p) => p.apiProvider === "zoo-gateway") | |
| if (zooGatewayProfiles.length === 0) { | |
| this.log("[ensureZooGatewayProfileSeeded] No zoo-gateway profile found, creating one") | |
| } else { | |
| let allUpToDate = true | |
| for (const entry of zooGatewayProfiles) { | |
| try { | |
| const fullProfile = await this.providerSettingsManager.getProfile({ name: entry.name }) | |
| if ( | |
| fullProfile.zooSessionToken !== token || | |
| fullProfile.zooGatewayBaseUrl !== derivedGatewayBaseUrl | |
| ) { | |
| allUpToDate = false | |
| this.log("[ensureZooGatewayProfileSeeded] Existing zoo-gateway profile is stale, updating") | |
| break | |
| } | |
| } catch { | |
| allUpToDate = false | |
| this.log("[ensureZooGatewayProfileSeeded] Failed to read existing profile, will re-seed") | |
| break | |
| } | |
| } | |
| if (allUpToDate) { | |
| // All profiles have the current token — nothing to do | |
| return | |
| } | |
| } | |
| // User has token but either no profile, some profiles without token, or stale tokens — seed all | |
| await this.handleZooCodeCallback(token) | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/core/webview/ClineProvider.ts` around lines 873 - 916,
ensureZooGatewayProfileSeeded currently only compares profile.zooSessionToken to
getCachedZooCodeToken(); also check that each profile.zooGatewayBaseUrl equals
the current getZooCodeBaseUrl() and treat any mismatch as stale so seeding
occurs. In the loop that inspects zooGatewayProfiles (using
providerSettingsManager.getProfile and the token check), fetch the current base
URL via getZooCodeBaseUrl(), compare it to fullProfile.zooGatewayBaseUrl, and if
different set allUpToDate = false, log a descriptive message, and break so
handleZooCodeCallback(token) will be invoked to reseed both tokens and base
URLs. Ensure references to ensureZooGatewayProfileSeeded, getCachedZooCodeToken,
getZooCodeBaseUrl, providerSettingsManager.getProfile, and handleZooCodeCallback
are used to locate the changes.
| }, | ||
| "googleCloudCredentials": "Google Cloud क्रेडेंशियल्स", | ||
| "googleCloudCredentialsPathWarning": "इस फ़ील्ड में सर्विस-अकाउंट कुंजी फ़ाइल की JSON सामग्री अपेक्षित है, पथ नहीं। यदि आपके पास पथ है, तो उसे नीचे दिए गए <strong>Google Cloud कुंजी फ़ाइल पथ</strong> फ़ील्ड में पेस्ट करें, या इस फ़ील्ड को खाली करें और <code>GOOGLE_APPLICATION_CREDENTIALS</code> पर्यावरण चर का उपयोग करें।", | ||
| "googleCloudCredentialsPathWarning": "इस फ़ील्ड में सर्विस-अकाउंट कुंजी फ़ाइल की JSON सामग्री अपेक्षित है, पथ नहीं। यदि आपके पास पथ है, तो उसे नीचे दिए गए <strong>Google Cloud कुंजी फ़ाइल पथ</strong> फ़ील्ड में पेस्ट करें, या इस फ़ील्ड को खाली करें और <code>GOOGLE_APPLICATION_CREDENTIALS</code> पर्यावरण चर का उपयोग करें।", |
There was a problem hiding this comment.
Replace mojibake strings with valid Hindi copy.
Line 455 and Line 871 contain unreadable encoded text, so critical setup/help content is broken for Hindi users.
Also applies to: 871-871
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@webview-ui/src/i18n/locales/hi/settings.json` at line 455, The string value
for "googleCloudCredentialsPathWarning" (and the other mojibake entry at line
871) contains garbled text; replace these mojibake strings with proper Hindi
translations while preserving inline HTML tags (<strong>, <code>) and meaning
about Google Cloud credentials and GOOGLE_APPLICATION_CREDENTIALS, updating the
JSON values for the keys (e.g., "googleCloudCredentialsPathWarning") so the
help/setup content reads correctly in Hindi.
| }, | ||
| "googleCloudCredentials": "Poświadczenia Google Cloud", | ||
| "googleCloudCredentialsPathWarning": "To pole oczekuje zawartości JSON pliku klucza konta usługi, a nie ścieżki. Jeśli masz ścieżkę, wklej ją do pola <strong>Ścieżka pliku klucza Google Cloud</strong> poniżej lub wyczyść to pole i użyj zmiennej środowiskowej <code>GOOGLE_APPLICATION_CREDENTIALS</code>.", | ||
| "googleCloudCredentialsPathWarning": "To pole oczekuje zawartości JSON pliku klucza konta usługi, a nie ścieżki. Jeśli masz ścieżkę, wklej ją do pola <strong>Ścieżka pliku klucza Google Cloud</strong> poniżej lub wyczyść to pole i użyj zmiennej środowiskowej <code>GOOGLE_APPLICATION_CREDENTIALS</code>.", |
There was a problem hiding this comment.
Replace mojibake in Polish localized messages.
Line 455 and Line 871 contain corrupted characters, making key setup and model-selection text hard to understand.
Also applies to: 871-871
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@webview-ui/src/i18n/locales/pl/settings.json` at line 455, The string value
for "googleCloudCredentialsPathWarning" contains mojibake (garbled Unicode) and
should be replaced with correctly encoded Polish text (use proper characters
like ą,ę,ś,ł,ż,ó,ć,ń) and similarly fix the corrupted message at the
model-selection key on the other occurrence (line ~871); open the JSON entry for
"googleCloudCredentialsPathWarning" and the model-selection key, replace the
garbled characters with the correct Polish phrasing, and ensure the file is
saved with UTF-8 encoding so the Polish diacritics persist.
| }, | ||
| "googleCloudCredentials": "Учётные данные Google Cloud", | ||
| "googleCloudCredentialsPathWarning": "Это поле ожидает JSON-содержимое файла ключа сервисного аккаунта, а не путь. Если у вас есть путь, вставьте его в поле <strong>Путь к ключу Google Cloud</strong> ниже, либо очистите это поле и используйте переменную окружения <code>GOOGLE_APPLICATION_CREDENTIALS</code>.", | ||
| "googleCloudCredentialsPathWarning": "Это поле ожидает JSON-содержимое файла ключа сервисного аккаунта, а не путь. Если у вас есть путь, вставьте его в поле <strong>Путь к ключу Google Cloud</strong> ниже, либо очистите это поле и используйте переменную окружения <code>GOOGLE_APPLICATION_CREDENTIALS</code>.", |
There was a problem hiding this comment.
Restore valid Russian text for the modified warning/help strings.
Line 455 and Line 871 are encoding-corrupted, so users can’t read key setup/model-selection guidance.
Also applies to: 871-871
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@webview-ui/src/i18n/locales/ru/settings.json` at line 455, The JSON values
for Russian locale contain encoding-corrupted text; replace the corrupted value
for the key "googleCloudCredentialsPathWarning" in settings.json with a proper
Russian translation and likewise locate and restore the other corrupted Russian
string near line 871 (search for non-UTF8/garbled characters) so both
warning/help messages are readable; ensure the replacements are valid UTF-8,
preserve existing HTML/inline code tags like <strong> and <code> exactly, and
run a quick JSON lint to confirm no syntax changes.
| }, | ||
| "googleCloudCredentials": "Thông tin xác thực Google Cloud", | ||
| "googleCloudCredentialsPathWarning": "Trường này mong đợi nội dung JSON của tệp khóa tài khoản dịch vụ, không phải đường dẫn. Nếu bạn có đường dẫn, hãy dán vào trường <strong>Đường dẫn tệp khóa Google Cloud</strong> bên dưới, hoặc xóa trường này và sử dụng biến môi trường <code>GOOGLE_APPLICATION_CREDENTIALS</code>.", | ||
| "googleCloudCredentialsPathWarning": "Trường này mong đợi nội dung JSON của tệp khóa tài khoản dịch vụ, không phải đường dẫn. Nếu bạn có đường dẫn, hãy dán vào trường <strong>Đường dẫn tệp khóa Google Cloud</strong> bên dưới, hoặc xóa trường này và sử dụng biến môi trường <code>GOOGLE_APPLICATION_CREDENTIALS</code>.", |
There was a problem hiding this comment.
Fix encoding-corrupted Vietnamese strings.
Line 455 and Line 871 are mojibake, so important provider instructions are unreadable in this locale.
Also applies to: 871-871
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@webview-ui/src/i18n/locales/vi/settings.json` at line 455, The string value
for the locale key "googleCloudCredentialsPathWarning" (and the other corrupted
Vietnamese entry in the same file) is mojibake; replace the corrupted text with
the correct Vietnamese translations, ensure the HTML (<strong>) and code
(<code>) fragments remain intact, save the file encoded as UTF-8 without BOM,
and validate the JSON (lint/parse) after the replacement so the locale renders
correctly.
| }, | ||
| "googleCloudCredentials": "Google Cloud 凭证", | ||
| "googleCloudCredentialsPathWarning": "此字段需要服务账号密钥文件的 JSON 内容,而不是路径。如果您有路径,请将其粘贴到下方的<strong>Google Cloud 密钥文件路径</strong>字段中,或清除此字段并使用 <code>GOOGLE_APPLICATION_CREDENTIALS</code> 环境变量。", | ||
| "googleCloudCredentialsPathWarning": "此字段需要服务账号密钥文件的 JSON 内容,而不是路径。如果您有路径,请将其粘贴到下方的<strong>Google Cloud 密钥文件路径</strong>字段中,或清除此字段并使用 <code>GOOGLE_APPLICATION_CREDENTIALS</code> 环境变量。", |
There was a problem hiding this comment.
Fix corrupted Simplified Chinese translations.
Line 455 and Line 871 are unreadable mojibake, which breaks important provider guidance in this locale.
Also applies to: 871-871
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@webview-ui/src/i18n/locales/zh-CN/settings.json` at line 455, Fix the
mojibake in the Simplified Chinese locale by replacing the corrupted string
value for the key "googleCloudCredentialsPathWarning" (and the other corrupted
entry at the second occurrence referenced) with a proper Simplified Chinese
translation that preserves the embedded HTML and code tags (<strong>...</strong>
and <code>GOOGLE_APPLICATION_CREDENTIALS</code>); locate the entries by the key
"googleCloudCredentialsPathWarning" and the other unreadable key near the same
block, correct the text to clear, idiomatic Chinese guidance about placing a
Google Cloud service account JSON file and setting
GOOGLE_APPLICATION_CREDENTIALS, and keep surrounding JSON syntax and punctuation
unchanged.
| case "zoo-gateway": | ||
| if (!apiConfiguration.zooSessionToken && !zooCodeIsAuthenticated) { | ||
| return i18next.t("settings:validation.zooGatewaySignIn") | ||
| } |
There was a problem hiding this comment.
Don't treat Zoo Code auth state as a substitute for a seeded gateway token.
This branch now accepts zoo-gateway while zooSessionToken is still missing. Since ensureZooGatewayProfileSeeded() is kicked off in the background during webview init, a signed-in user can pass validation and start a request before the profile has actually been repaired, so the first gateway call is still unauthenticated. Keep validation gated on the stored token, or block Zoo Gateway until seeding completes.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@webview-ui/src/utils/validate.ts` around lines 130 - 133, The validation for
"zoo-gateway" currently accepts a user if zooCodeIsAuthenticated is true even
when apiConfiguration.zooSessionToken is missing; change the condition in
validate.ts (the "zoo-gateway" case) to require the persisted token
(apiConfiguration.zooSessionToken) be present before passing validation and do
not treat zooCodeIsAuthenticated as a substitute, or alternatively add and check
a seeding-complete flag (set by ensureZooGatewayProfileSeeded) so validation
only passes when the stored token is present or seeding has finished; update the
return logic that currently references apiConfiguration.zooSessionToken and
zooCodeIsAuthenticated accordingly.
89559d5 to
9750f48
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/i18n/locales/tr/common.json`:
- Around line 264-278: This PR includes new Turkish locale keys
(could_not_verify_token, session_expired, out_of_credits, account_unavailable,
budget_exceeded, info.connected, info.disconnected, buttons.sign_in,
buttons.add_credits, buttons.contact_support) that are unrelated to the stated
privacy/telemetry changes; please confirm whether these i18n additions are part
of a separate Zoo Gateway auth/billing feature and if so remove them from this
branch and open a dedicated PR for the Gateway UX, otherwise update the PR
description to list these locale changes; also verify that the intended
privacy/telemetry edits (PRIVACY.md and zoo-telemetry.ts) are present on the
branch—if they are missing, add those files/changes or point to the correct
branch/commit that contains them before merging.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 098eec11-2d23-4f57-b28f-37e11d4eb16d
📒 Files selected for processing (20)
PRIVACY.mdsrc/i18n/locales/ca/common.jsonsrc/i18n/locales/de/common.jsonsrc/i18n/locales/es/common.jsonsrc/i18n/locales/fr/common.jsonsrc/i18n/locales/hi/common.jsonsrc/i18n/locales/id/common.jsonsrc/i18n/locales/it/common.jsonsrc/i18n/locales/ja/common.jsonsrc/i18n/locales/ko/common.jsonsrc/i18n/locales/nl/common.jsonsrc/i18n/locales/pl/common.jsonsrc/i18n/locales/pt-BR/common.jsonsrc/i18n/locales/ru/common.jsonsrc/i18n/locales/tr/common.jsonsrc/i18n/locales/vi/common.jsonsrc/i18n/locales/zh-CN/common.jsonsrc/i18n/locales/zh-TW/common.jsonsrc/services/__tests__/zoo-telemetry.test.tssrc/services/zoo-telemetry.ts
✅ Files skipped from review due to trivial changes (8)
- src/i18n/locales/nl/common.json
- src/i18n/locales/it/common.json
- PRIVACY.md
- src/i18n/locales/ko/common.json
- src/i18n/locales/ca/common.json
- src/i18n/locales/de/common.json
- src/i18n/locales/ja/common.json
- src/i18n/locales/pl/common.json
🚧 Files skipped from review as they are similar to previous changes (1)
- src/services/tests/zoo-telemetry.test.ts
The downstream stack (settings-ui) calls getCachedZooCodeToken and clearZooCodeToken from the auth handler. CI on stacked PRs merges base into head so this spec runs against the cached-token-aware handler; expand the auth module mock so the auth guard test exercises the real throw path instead of vitest's missing-mock-export error. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
- Resolve ModelPicker serviceUrl from zooCodeBaseUrl so staging/dev environments link to the matching dashboard. - Fall back to getCachedZooCodeToken() in the handler and model fetcher when the profile has not been seeded yet (auth before webview open). Co-authored-by: Cursor <cursoragent@cursor.com>
…-lockfile installs Co-authored-by: Cursor <cursoragent@cursor.com>
…ch 'free' search hint dropped on rebase Co-authored-by: Cursor <cursoragent@cursor.com>
… 4.5 Resolves Sonnet 4.5 from the gateway model catalog instead of a static Vercel slug so test (Bedrock) and live accounts both get a valid default. Reassigns stale profile model IDs when they are not in the catalog. Co-authored-by: Cursor <cursoragent@cursor.com>
Exports pickZooGatewayDefaultModelId so the helper is unit-testable and adds component tests for the auto-default useEffect (no-op while catalog loads, auto-pick on empty profile, repair stale id, no-op when valid). Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Add ClineProvider tests for handleZooCodeCallback, ensureZooGatewayProfileSeeded, and webviewMessageHandler zooCodeSignOut to satisfy codecov patch on PR #347. Co-authored-by: Cursor <cursoragent@cursor.com>
Clear the cached token on 401 and offer sign-in. On insufficient credits or budget limits, open the credits page. On account frozen/banned, open support. Errors still propagate to the task layer after the toast. Co-authored-by: Cursor <cursoragent@cursor.com>
…ocales Adds session_expired, out_of_credits, account_unavailable, budget_exceeded under zooAuth.errors and a new zooAuth.buttons block (sign_in, add_credits, contact_support) introduced by the gateway 401/402/403 UX so check-translations passes. Co-authored-by: Cursor <cursoragent@cursor.com>
…ov patch Adds vscode + i18n mocks and asserts the 401/402/403/429 paths in surfaceGatewayApiError: token clear + sign-in URL on 401, add-credits URL on 402 and budget-coded 429, support URL on 403, no-op on 429 without a budget code or on errors without a status. Also verifies the helper still runs before completePrompt rewraps the upstream error. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…tion gating expectation Co-authored-by: Cursor <cursoragent@cursor.com>
9750f48 to
91f52ae
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/core/webview/webviewMessageHandler.ts`:
- Around line 956-963: The code currently picks the first zoo-gateway profile
from provider.providerSettingsManager.listConfig() and uses its token, which
fails if that profile lacks zooSessionToken; instead, iterate or map over all
profiles where p.apiProvider === "zoo-gateway", fetch each profile via
provider.providerSettingsManager.getProfile({ name: ... }) (e.g., Promise.all or
sequentially), and select the first fullProfile with a truthy
fullProfile.zooSessionToken, then assign zooGatewayToken =
fullProfile.zooSessionToken and zooGatewayBaseUrl =
fullProfile.zooGatewayBaseUrl ?? zooGatewayBaseUrl; ensure you fall back to the
previous base URL if none found.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 9aa8a0a1-882a-4229-9619-5e386802f9f7
📒 Files selected for processing (59)
PRIVACY.mdsrc/activate/__tests__/handleUri.spec.tssrc/activate/handleUri.tssrc/api/providers/__tests__/zoo-gateway.spec.tssrc/api/providers/fetchers/__tests__/zoo-gateway.spec.tssrc/api/providers/fetchers/zoo-gateway.tssrc/api/providers/zoo-gateway.tssrc/core/webview/ClineProvider.tssrc/core/webview/__tests__/ClineProvider.spec.tssrc/core/webview/__tests__/webviewMessageHandler.spec.tssrc/core/webview/webviewMessageHandler.tssrc/i18n/locales/ca/common.jsonsrc/i18n/locales/de/common.jsonsrc/i18n/locales/en/common.jsonsrc/i18n/locales/es/common.jsonsrc/i18n/locales/fr/common.jsonsrc/i18n/locales/hi/common.jsonsrc/i18n/locales/id/common.jsonsrc/i18n/locales/it/common.jsonsrc/i18n/locales/ja/common.jsonsrc/i18n/locales/ko/common.jsonsrc/i18n/locales/nl/common.jsonsrc/i18n/locales/pl/common.jsonsrc/i18n/locales/pt-BR/common.jsonsrc/i18n/locales/ru/common.jsonsrc/i18n/locales/tr/common.jsonsrc/i18n/locales/vi/common.jsonsrc/i18n/locales/zh-CN/common.jsonsrc/i18n/locales/zh-TW/common.jsonsrc/services/__tests__/zoo-telemetry.test.tssrc/services/zoo-telemetry.tswebview-ui/src/components/settings/ApiOptions.tsxwebview-ui/src/components/settings/ModelPicker.tsxwebview-ui/src/components/settings/__tests__/ApiOptions.spec.tsxwebview-ui/src/components/settings/constants.tswebview-ui/src/components/settings/providers/ZooGateway.tsxwebview-ui/src/components/settings/providers/__tests__/ZooGateway.spec.tsxwebview-ui/src/components/settings/providers/index.tswebview-ui/src/components/welcome/WelcomeViewProvider.tsxwebview-ui/src/i18n/locales/ca/settings.jsonwebview-ui/src/i18n/locales/de/settings.jsonwebview-ui/src/i18n/locales/en/settings.jsonwebview-ui/src/i18n/locales/es/settings.jsonwebview-ui/src/i18n/locales/fr/settings.jsonwebview-ui/src/i18n/locales/hi/settings.jsonwebview-ui/src/i18n/locales/id/settings.jsonwebview-ui/src/i18n/locales/it/settings.jsonwebview-ui/src/i18n/locales/ja/settings.jsonwebview-ui/src/i18n/locales/ko/settings.jsonwebview-ui/src/i18n/locales/nl/settings.jsonwebview-ui/src/i18n/locales/pl/settings.jsonwebview-ui/src/i18n/locales/pt-BR/settings.jsonwebview-ui/src/i18n/locales/ru/settings.jsonwebview-ui/src/i18n/locales/tr/settings.jsonwebview-ui/src/i18n/locales/vi/settings.jsonwebview-ui/src/i18n/locales/zh-CN/settings.jsonwebview-ui/src/i18n/locales/zh-TW/settings.jsonwebview-ui/src/utils/validate.tswebview-ui/vite.config.ts
✅ Files skipped from review due to trivial changes (13)
- webview-ui/src/components/settings/providers/index.ts
- webview-ui/src/components/settings/constants.ts
- PRIVACY.md
- src/i18n/locales/ru/common.json
- src/i18n/locales/hi/common.json
- webview-ui/src/i18n/locales/id/settings.json
- src/i18n/locales/ja/common.json
- src/i18n/locales/vi/common.json
- webview-ui/src/i18n/locales/en/settings.json
- webview-ui/src/i18n/locales/es/settings.json
- src/i18n/locales/pl/common.json
- src/i18n/locales/tr/common.json
- src/i18n/locales/pt-BR/common.json
🚧 Files skipped from review as they are similar to previous changes (40)
- webview-ui/src/i18n/locales/de/settings.json
- webview-ui/src/components/welcome/WelcomeViewProvider.tsx
- webview-ui/src/components/settings/ModelPicker.tsx
- src/i18n/locales/es/common.json
- src/i18n/locales/id/common.json
- webview-ui/src/utils/validate.ts
- webview-ui/src/components/settings/tests/ApiOptions.spec.tsx
- webview-ui/src/components/settings/ApiOptions.tsx
- webview-ui/vite.config.ts
- src/services/tests/zoo-telemetry.test.ts
- webview-ui/src/i18n/locales/zh-CN/settings.json
- src/services/zoo-telemetry.ts
- src/activate/tests/handleUri.spec.ts
- src/api/providers/fetchers/zoo-gateway.ts
- src/api/providers/fetchers/tests/zoo-gateway.spec.ts
- webview-ui/src/i18n/locales/ru/settings.json
- webview-ui/src/i18n/locales/nl/settings.json
- webview-ui/src/i18n/locales/tr/settings.json
- src/i18n/locales/ca/common.json
- src/i18n/locales/zh-CN/common.json
- webview-ui/src/i18n/locales/vi/settings.json
- webview-ui/src/i18n/locales/pt-BR/settings.json
- src/i18n/locales/nl/common.json
- src/core/webview/ClineProvider.ts
- src/i18n/locales/zh-TW/common.json
- webview-ui/src/i18n/locales/ko/settings.json
- src/core/webview/tests/ClineProvider.spec.ts
- webview-ui/src/i18n/locales/zh-TW/settings.json
- webview-ui/src/i18n/locales/ja/settings.json
- src/i18n/locales/it/common.json
- src/api/providers/zoo-gateway.ts
- src/i18n/locales/fr/common.json
- webview-ui/src/i18n/locales/pl/settings.json
- webview-ui/src/components/settings/providers/ZooGateway.tsx
- webview-ui/src/i18n/locales/ca/settings.json
- src/i18n/locales/en/common.json
- src/core/webview/tests/webviewMessageHandler.spec.ts
- webview-ui/src/i18n/locales/fr/settings.json
- src/activate/handleUri.ts
- webview-ui/src/i18n/locales/it/settings.json
| const allProfiles = await provider.providerSettingsManager.listConfig() | ||
| const zooGatewayProfile = allProfiles.find((p) => p.apiProvider === "zoo-gateway") | ||
| if (zooGatewayProfile) { | ||
| const fullProfile = await provider.providerSettingsManager.getProfile({ | ||
| name: zooGatewayProfile.name, | ||
| }) | ||
| zooGatewayToken = fullProfile.zooSessionToken | ||
| zooGatewayBaseUrl = fullProfile.zooGatewayBaseUrl ?? zooGatewayBaseUrl |
There was a problem hiding this comment.
Search all zoo-gateway profiles for a usable token.
Line 957 selects only the first zoo-gateway profile. If that profile has no zooSessionToken, model fetch can fail even when another zoo-gateway profile has a valid token.
💡 Suggested fix
- const zooGatewayProfile = allProfiles.find((p) => p.apiProvider === "zoo-gateway")
- if (zooGatewayProfile) {
- const fullProfile = await provider.providerSettingsManager.getProfile({
- name: zooGatewayProfile.name,
- })
- zooGatewayToken = fullProfile.zooSessionToken
- zooGatewayBaseUrl = fullProfile.zooGatewayBaseUrl ?? zooGatewayBaseUrl
- }
+ const zooGatewayProfiles = allProfiles.filter((p) => p.apiProvider === "zoo-gateway")
+ for (const profileMeta of zooGatewayProfiles) {
+ const fullProfile = await provider.providerSettingsManager.getProfile({ name: profileMeta.name })
+ if (fullProfile.zooSessionToken) {
+ zooGatewayToken = fullProfile.zooSessionToken
+ zooGatewayBaseUrl = fullProfile.zooGatewayBaseUrl ?? zooGatewayBaseUrl
+ break
+ }
+ }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/core/webview/webviewMessageHandler.ts` around lines 956 - 963, The code
currently picks the first zoo-gateway profile from
provider.providerSettingsManager.listConfig() and uses its token, which fails if
that profile lacks zooSessionToken; instead, iterate or map over all profiles
where p.apiProvider === "zoo-gateway", fetch each profile via
provider.providerSettingsManager.getProfile({ name: ... }) (e.g., Promise.all or
sequentially), and select the first fullProfile with a truthy
fullProfile.zooSessionToken, then assign zooGatewayToken =
fullProfile.zooSessionToken and zooGatewayBaseUrl =
fullProfile.zooGatewayBaseUrl ?? zooGatewayBaseUrl; ensure you fall back to the
previous base URL if none found.
Summary
Independent of Zoo Gateway provider code (split from #229 per review).
Test plan
Made with Cursor
Summary by CodeRabbit
Documentation
New Features
Bug Fixes / Reliability