fix(providers): allow replacing preferred models#1104
Conversation
Greptile SummaryThis PR fixes preferred-model preferences so that saving a new selection fully replaces the old one — both in persistent key-store and in the in-memory cross-provider priority list — and pre-populates the dialog with the current saved selection.
Confidence Score: 5/5Safe to merge — the replace logic is correct, the failure path (save_config error) leaves the priority list untouched, and both the backend unit tests and the Playwright spec exercise the key scenarios. The three changed files are tightly scoped: the Rust side correctly evicts old models before inserting new ones, the TypeScript side resolves the bare-name vs namespaced-ID mismatch, and the tests validate both behaviours end-to-end. No edge cases were found that the new code mishandles. No files require special attention.
|
| Filename | Overview |
|---|---|
| crates/provider-setup/src/service/implementation/credentials.rs | Adds previous-model eviction from the priority list before inserting the new selection; load/save ordering is correct, error path leaves priority list untouched, and two unit tests verify both replace and clear cases. |
| crates/web/ui/src/providers/auth-flow.ts | Pre-selects saved preferences in the multi-model dialog using a dual-lookup strategy (direct ID match + namespace-stripped token match) to handle the bare-name vs fully-qualified-ID mismatch between key-store and models.list. |
| crates/web/ui/e2e/specs/providers.spec.js | New Playwright test mocks both models.list and providers.available, verifies the dialog pre-selects both saved models, deselects one, and confirms the save RPC carries only the remaining selected model. |
Sequence Diagram
sequenceDiagram
participant UI as auth-flow.ts
participant WS as WebSocket RPC
participant SVC as save_models_inner
participant KS as KeyStore
participant PL as PriorityList (RwLock)
UI->>WS: "models.list {}"
WS-->>UI: "[{id:"openai::gpt-a", ...}, ...]"
UI->>WS: "providers.available {}"
WS-->>UI: "[{name:"openai", models:["gpt-a","gpt-b"]}]"
Note over UI: Build selectedIds by matching model.id vs savedModels using stripModelNamespace fallback
UI->>UI: User deselects gpt-b
UI->>WS: "providers.save_models {provider:"openai", models:["openai::gpt-a"]}"
WS->>SVC: save_models_inner(params)
SVC->>KS: load_config("openai") → ["gpt-a","gpt-b"]
SVC->>KS: "save_config("openai", models=["gpt-a"])"
SVC->>PL: write lock acquired
loop for each previous model
PL->>PL: "retain(existing != previous)"
end
loop for each new model (rev)
PL->>PL: retain + insert(0, m)
end
SVC-->>UI: "{ok: true}"
Reviews (1): Last reviewed commit: "fix(providers): allow replacing preferre..." | Re-trigger Greptile
Merging this PR will not alter performance
Comparing Footnotes
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Summary
Validation
Completed
cargo fmt --all -- --checkcargo test -p moltis-provider-setup save_models_npm run buildnpm run build:allnpx tsc --noEmitnpx playwright test e2e/specs/providers.spec.jsRemaining
Manual QA
Fixes #1094