Repository navigation
fix(cursor): a completed catalog refresh drops models it no longer lists - #28018
juliusmarminge wants to merge 3 commits into
Conversation
…refresh These tests reproduce #28008: a ready Cursor probe should replace the model list, while a failed probe keeps the previous models. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cursor fell through to the default "retain missing models" rule, so a refresh could only add models and a previous account's or retired plan's models stayed in the snapshot and provider cache forever. Cursor reports ready only after a non-empty SDK catalog read, the same contract as Grok, so it now shares Grok's rule: a ready probe replaces the list, while warning/error probes keep the previous models. Two generic retention tests used Cursor with a ready, empty refresh, a state the Cursor probe never produces; they now use the warning status an empty catalog actually reports. Fixes #28008 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — Completed Cursor catalog refreshes now remove stale models from the picker and cache. Failed, pending, and empty-catalog probes continue preserving previously discovered models, limiting the change to successfully refreshed inventory. You can add or adjust custom eligibility rules. Learn more. |
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Model retention and refresh coverage apps/server/src/provider/ProviderRegistry.ts, apps/server/src/provider/ProviderRegistry.test.ts |
Cursor retains previous models unless it is installed and ready. Tests verify that a completed refresh drops unlisted models, an error refresh retains prior models, and warning-status snapshots exercise the retention behavior. |
Estimated code review effort: 2 (Simple) | ~10 minutes
Change: Bug fix · Severity of issue fixed: Medium
Suggested labels: size:XS
Suggested reviewers: t3dotgg
Merge Risk: 
Minimal · up to ba75e
-
Ready Cursor refreshes replace stale models while failed discovery retains them. No merge-blocking risk remains.
Pre-merge checks: 
4
-
Full details: Title check
-
Explanation
The title names the Cursor fix directly: a completed catalog refresh now drops models the catalog no longer lists. The raw summary and the objectives both describe a Cursor retention change in ProviderRegistry that does this. The title is specific and concise and follows the conventional commit form. It is 72 characters, which is slightly above the usual 72-character guideline, but this does not affect the assessment.
Full details: Description check
-
Explanation
The description follows the repository template. It has a Problem section that gives the reproduction on main and the expected behavior. It has a Change section that explains the Cursor retention rule and the test fixture updates. It has a Scope and approval section that links issue
#28008and notes the automated triage flow. It has a Verification section with the focused test results, the check:changed results, and a runtime transcript. It also lists what was not checked. The template asks for a maintainer-approval link or an explicit exemption for a small fix. The author gives a link to the issue and says it was triaged through an automated flow, but does not show explicit maintainer approval. The template also asks that the agent model and harness be named at the end, and the description does this.Resolution
Optional: confirm that the triage of issue
#28008meets the approval rule in the template. The description links the issue but does not include an explicit maintainer approval comment or discussion. If no maintainer approval exists, add a link to it or explain why this small, focused fix of an obvious bug does not need one.
Full details: Linked Issues check
-
Explanation
Issue
#28008requires Cursor refreshes to remove models absent from a successful catalog read while retaining models when discovery fails.ProviderRegistry.tsapplies the existing Grok rule to Cursor: an installedreadyprovider replaces missing models, while non-ready providers retain them. The new registry test verifies both Cursor model removal after a ready refresh and retention after an error refresh. The suggested identity-mismatch safeguard is complementary and is not required for the refresh-based behavior implemented here.
Full details: Out of Scope Changes check
-
Explanation
The changes stay within issue
#28008. They modify Cursor model-retention behavior and update two Cursor empty-catalog fixtures fromreadytowarning, matching the provider contract. The added test covers the requested success and failure paths. No unrelated provider behavior or unrelated files changed.
-
Finishing Touches
-
Generate docstrings
-
- Commit to this branch
- Create a new PR
Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Problem
The Cursor model list could only grow. Every provider refresh merged the previous snapshot's models into the new catalog, and the result was persisted to
caches/cursor.json. Models from a previous Cursor account, a downgraded plan, or a retired model therefore stayed in the picker indefinitely, even when the catalog read succeeded and listed fewer models.Reproduction on
main(b823dcf): with Cursor ready on a fresh home, I appended three models the catalog does not return tocaches/cursor.json. A restart and Settings > Providers > "Refresh provider status" both completed with statusready, and both still listed all 51 models, the three stale ones included.Change
shouldRetainMissingProviderModelshad no Cursor clause, so Cursor fell through toreturn true(always keep the missing models). Cursor now shares Grok's existing rule. Previous models are kept only while the probe is notinstalled && status === "ready". Cursor's status probe reportsreadyonly when the SDK catalog read succeeded with at least one model. The initial placeholder, an empty catalog, a failed or timed-out read, and a missing key are allwarningorerror, and those still keep the previous models. A completed refresh replaces the list, and that replacement also reaches the persisted cache.Two existing registry tests used Cursor as a stand-in for generic retention, with a
readyrefresh that returned no models. The Cursor probe never reports that state. Those fixtures now usewarning, which is what an empty catalog reports, so they still exercise the same retention behaviour.Other drivers that fall through to the default (
claudeAgent,fx,muse) are deliberately left unchanged.Scope and approval
Fixes #28008
Triaged via the automated issue flow.
Verification
drops Cursor models a completed catalog read no longer returnsinapps/server/src/provider/ProviderRegistry.test.ts. It fails onmain(retired-model-xis still appended after a ready refresh) and passes with the fix. Its second assertion checks that a failed (error) refresh still keeps the previous models.vp test run apps/server/src/provider/ProviderRegistry.test.ts: 49/49 pass.vp run check:changedafter merging main: format, lint, knip, typecheck (3 packages) and tests (2 files, 50 tests) pass.T3CODE_DEV_SEED=0 vp run dev, fresh database, Cursor viaCURSOR_API_KEY). The stale models are synthetic slugs written into the cache file:Model and harness: Claude Opus 5.5 (claude-opus-5-5) and GPT-6.1-Sol in T3 Code via Claude Code and Codex.
🤖 Generated with Claude Code