fix: persist default kimi hub provider to BrowserOS prefs on first load#491
Conversation
When VITE_PUBLIC_KIMI_LAUNCH is enabled, loadProviders() returned default Kimi provider in-memory but never saved it to the BrowserOS pref. The browser's C++ code reads the pref directly and found it empty, so Kimi didn't appear in the toolbar until the user manually edited and saved. Now loadProviders() persists defaults and ensureKimiFirst() additions to the pref, keeping the browser in sync with what the extension UI shows. Fixes #428 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Greptile (@greptileai) review |
Greptile SummaryThis PR fixes a bug where the default Kimi hub provider was only returned in-memory but never persisted to the BrowserOS pref, causing the C++ browser layer to read an empty pref and not display Kimi in the toolbar until the user manually saved. Key changes in
Observations:
Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant UI as React UI (useLlmHubProviders)
participant S as storage.ts (loadProviders)
participant A as BrowserOSAdapter
participant P as BrowserOS Prefs (C++)
UI->>S: loadProviders()
S->>A: getPref(THIRD_PARTY_LLM_PROVIDERS)
A->>P: chrome.browserOS.getPref(...)
P-->>A: PrefObject (value or empty)
A-->>S: providers[]
alt providers is empty AND Kimi launch enabled
S->>A: saveProviders([KIMI_PROVIDER])
A->>P: chrome.browserOS.setPref(..., [KIMI_PROVIDER])
Note over P: Kimi now visible to C++ toolbar
P-->>A: success
A-->>S: boolean
S-->>UI: [KIMI_PROVIDER]
else providers is empty AND Kimi launch disabled
S-->>UI: []
else providers not empty
S->>S: ensureKimiFirst(providers)
alt Kimi was NOT in list (length changed)
S->>A: saveProviders(normalized)
A->>P: chrome.browserOS.setPref(..., normalized)
Note over P: Kimi prepended & persisted
P-->>A: success
A-->>S: boolean
end
S-->>UI: normalized
end
Prompt To Fix All With AIThis is a comment left during a code review.
Path: apps/agent/lib/llm-hub/storage.ts
Line: 42-44
Comment:
**Fragile save condition: length check misses reorders**
The condition `normalized.length !== providers.length` works correctly for `ensureKimiFirst`'s current implementation, which only ever prepends Kimi. However, `ensureKimiFirst` already returns the **same object reference** when unchanged (`return hasKimi ? providers : [KIMI_PROVIDER, ...providers]`), so a reference inequality check is both more semantically precise and more future-proof — it would also catch any future change to `ensureKimiFirst` that reorders items (e.g. moving Kimi from the middle to the front) without changing the length.
```suggestion
const normalized = ensureKimiFirst(providers)
if (normalized !== providers) {
await saveProviders(normalized)
}
return normalized
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: apps/agent/lib/llm-hub/storage.ts
Line: 32-36
Comment:
**`saveProviders` return value not checked**
The result of `await saveProviders(defaults)` is silently discarded. `saveProviders` swallows errors and returns `false` when `setPref` fails, so if the pref write doesn't succeed the function still returns `defaults` to the caller — meaning the C++ side won't see Kimi in the pref even though the in-memory state looks correct. The fix retries on the *next* `loadProviders()` call (since prefs will still be empty), but there's no visibility into the failure. Consider at least logging when the save returns `false`, or propagating the result to aid debugging.
```suggestion
if (isKimiLaunchEnabled()) {
const defaults = [KIMI_PROVIDER]
const saved = await saveProviders(defaults)
if (!saved) {
// setPref failed; C++ will retry on next loadProviders call
}
return defaults
}
```
How can I resolve this? If you propose a fix, please make it concise.Last reviewed commit: 31b1b11 |
| if (normalized.length !== providers.length) { | ||
| await saveProviders(normalized) | ||
| } |
There was a problem hiding this comment.
Fragile save condition: length check misses reorders
The condition normalized.length !== providers.length works correctly for ensureKimiFirst's current implementation, which only ever prepends Kimi. However, ensureKimiFirst already returns the same object reference when unchanged (return hasKimi ? providers : [KIMI_PROVIDER, ...providers]), so a reference inequality check is both more semantically precise and more future-proof — it would also catch any future change to ensureKimiFirst that reorders items (e.g. moving Kimi from the middle to the front) without changing the length.
| if (normalized.length !== providers.length) { | |
| await saveProviders(normalized) | |
| } | |
| const normalized = ensureKimiFirst(providers) | |
| if (normalized !== providers) { | |
| await saveProviders(normalized) | |
| } | |
| return normalized |
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/agent/lib/llm-hub/storage.ts
Line: 42-44
Comment:
**Fragile save condition: length check misses reorders**
The condition `normalized.length !== providers.length` works correctly for `ensureKimiFirst`'s current implementation, which only ever prepends Kimi. However, `ensureKimiFirst` already returns the **same object reference** when unchanged (`return hasKimi ? providers : [KIMI_PROVIDER, ...providers]`), so a reference inequality check is both more semantically precise and more future-proof — it would also catch any future change to `ensureKimiFirst` that reorders items (e.g. moving Kimi from the middle to the front) without changing the length.
```suggestion
const normalized = ensureKimiFirst(providers)
if (normalized !== providers) {
await saveProviders(normalized)
}
return normalized
```
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Good catch — accepted. Reference equality is cleaner and more future-proof here since ensureKimiFirst returns the same array reference when unchanged. Updated to normalized !== providers.
|
Re: |
Address PR review: reference check (normalized !== providers) is more semantically precise than length comparison since ensureKimiFirst returns the same reference when unchanged. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
VITE_PUBLIC_KIMI_LAUNCHis enabled,loadProviders()inllm-hub/storage.tsreturned the default Kimi provider in-memory but never persisted it to the BrowserOS prefloadProviders()persists defaults andensureKimiFirst()additions to the pref immediatelyFixes #428
Test plan
VITE_PUBLIC_KIMI_LAUNCH=true→ Kimi should appear in hub without manual edit/saveVITE_PUBLIC_KIMI_LAUNCH=false→ No change in behavior🤖 Generated with Claude Code