Skip to content

Probe Cursor models via list_available_models#2428

Merged
juliusmarminge merged 7 commits into
mainfrom
t3code/cursor-model-probe
Jun 3, 2026
Merged

Probe Cursor models via list_available_models#2428
juliusmarminge merged 7 commits into
mainfrom
t3code/cursor-model-probe

Conversation

@juliusmarminge
Copy link
Copy Markdown
Member

@juliusmarminge juliusmarminge commented May 1, 2026

Summary

  • Add support for Cursor's cursor/list_available_models ACP extension to discover models and their config-driven capabilities.
  • Simplify Cursor capability discovery by using the extension response first, with a fallback to the existing config-options path.
  • Update the mock ACP agent and tests to cover the new discovery flow and reduced probe fan-out.

Testing

  • bun run test apps/server/src/provider/Layers/CursorProvider.test.ts
  • bun fmt
  • bun lint
  • bun typecheck

Open in Devin Review

Note

Medium Risk
Changes how Cursor provider models and capabilities are populated (single extension call vs. background probes), which affects model picker behavior if the extension response differs from the old path.

Overview
Cursor model discovery now uses Cursor’s cursor/list_available_models ACP extension during provider status checks instead of deriving models from session/new config options and probing each model in the background.

The server decodes responses with a new CursorListAvailableModelsResponse schema and maps each entry’s per-model configOptions into provider models and capabilities via existing buildCursorCapabilitiesFromConfigOptions. discoverCursorModelCapabilitiesViaAcp, session-based model listing helpers, and the multi-runtime capability probe path are removed.

enrichCursorSnapshot no longer runs ACP capability enrichment; it only applies version-advisory updates when the provider is enabled and authenticated. CursorDriver drops the extra spawner/environment wiring that supported background probes.

The mock ACP agent implements cursor/list_available_models with a static catalog and model-specific config options. Tests are updated accordingly; capability-probe and session/new discovery tests are removed.

Reviewed by Cursor Bugbot for commit efd96ae. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Probe Cursor models via cursor/list_available_models ACP extension

  • Replaces the previous per-model capability probing approach (switching models and scraping config options) with a single cursor/list_available_models ACP request that returns all models and their config options at once.
  • Adds CursorListAvailableModelsResponse schema in CursorAcpExtension.ts to decode the response, and buildCursorDiscoveredModelsFromAvailableModelsResponse in CursorProvider.ts to map it to ServerProviderModel entries.
  • Simplifies enrichCursorSnapshot to only publish version advisory metadata; background capability re-probing during enrichment is removed.
  • Adds cursor/list_available_models handler support to the ACP mock agent for local testing.
  • Behavioral Change: model capabilities are now captured in a single request at discovery time rather than incrementally during provider status checks.

Macroscope summarized efd96ae.

- Add `cursor/list_available_models` support to the ACP mock agent
- Use the new model list response for Cursor model discovery and capability enrichment
- Update tests to cover the extension path and reduced probe teardown
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 5fe85b36-0713-4959-a2f7-715447f9da66

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch t3code/cursor-model-probe

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels May 1, 2026
- Add a schema for `cursor/list_available_models` responses
- Use decoded model data when building Cursor provider capabilities
- Cover per-model config options in Cursor ACP tests
@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented May 1, 2026

Approvability

Verdict: Needs human review

Significant change to Cursor model discovery mechanism with removal of fallback behavior. Open review comment identifies potential regression when the new list_available_models extension is unavailable.

You can customize Macroscope's approvability policy. Learn more.

Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Capability enrichment lacks fallback unlike model discovery
    • Added Effect.catchCause fallback to discoverCursorModelCapabilitiesViaAcp that falls back to the config-options approach via session setup, matching the existing pattern in discoverCursorModelsViaAcp.

Create PR

Or push these changes by commenting:

@cursor push 4751b3d485
Preview (4751b3d485)
diff --git a/apps/server/src/provider/Layers/CursorProvider.ts b/apps/server/src/provider/Layers/CursorProvider.ts
--- a/apps/server/src/provider/Layers/CursorProvider.ts
+++ b/apps/server/src/provider/Layers/CursorProvider.ts
@@ -576,6 +576,15 @@
   _existingModels: ReadonlyArray<ServerProviderModel>,
 ) =>
   discoverCursorModelsViaListAvailableModels(cursorSettings).pipe(
+    Effect.catchCause(() =>
+      withCursorAcpProbeRuntime(cursorSettings, (acp) =>
+        Effect.map(acp.start(), (started) =>
+          buildCursorDiscoveredModelsFromConfigOptions(
+            started.sessionSetupResult.configOptions ?? [],
+          ),
+        ),
+      ),
+    ),
     Effect.withSpan("cursor-acp-model-capability-discovery", {}),
   );

You can send follow-ups to the cloud agent here.

Comment thread apps/server/src/provider/Layers/CursorProvider.ts Outdated
Resolve Cursor provider conflicts by keeping main's environment-aware provider runtime plumbing while preserving list_available_models discovery.

Co-authored-by: codex <codex@users.noreply.github.com>
…robe

# Conflicts:
#	apps/server/src/provider/Layers/CursorProvider.ts
#	apps/server/src/provider/acp/CursorAcpExtension.ts
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Enrichment shrinks model catalog
    • Merged base snapshot models with discovered models during enrichment so that models from the initial snapshot (e.g. from session config fallback) are preserved when list_available_models returns a shorter list.

Create PR

Or push these changes by commenting:

@cursor push 9bd61ebce7
Preview (9bd61ebce7)
diff --git a/apps/server/src/provider/Layers/CursorProvider.ts b/apps/server/src/provider/Layers/CursorProvider.ts
--- a/apps/server/src/provider/Layers/CursorProvider.ts
+++ b/apps/server/src/provider/Layers/CursorProvider.ts
@@ -1216,11 +1216,16 @@
           if (discoveredModels.length === 0) {
             return Effect.void;
           }
+          const discoveredSlugs = new Set(discoveredModels.map((m) => m.slug));
+          const mergedModels = [
+            ...discoveredModels,
+            ...baseSnapshot.models.filter((m) => !discoveredSlugs.has(m.slug)),
+          ];
           return publishSnapshot(
             stampIdentity({
               ...baseSnapshot,
               models: providerModelsFromSettings(
-                discoveredModels,
+                mergedModels,
                 PROVIDER,
                 settings.customModels,
                 EMPTY_CAPABILITIES,

You can send follow-ups to the cloud agent here.

Comment thread apps/server/src/provider/Layers/CursorProvider.ts
export const discoverCursorModelsViaAcp = (
cursorSettings: CursorSettings,
environment: NodeJS.ProcessEnv = process.env,
) => discoverCursorModelsViaListAvailableModels(cursorSettings, environment);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing config options discovery fallback

Medium Severity

discoverCursorModelsViaAcp now only calls cursor/list_available_models and no longer falls back to building models from session/new config options when that extension fails or is unsupported. Authenticated status checks then surface a discovery warning and publish no built-in models, which regresses behavior that previously worked against standard ACP session setup.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a6c9842. Configure here.

Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Version advisory enrichment skipped
    • Removed the early return that gated version advisory enrichment on settings.enabled and auth status, aligning Cursor with the Claude and Codex drivers which always run enrichProviderSnapshotWithVersionAdvisory unconditionally.

Create PR

Or push these changes by commenting:

@cursor push 1a86cdd225
Preview (1a86cdd225)
diff --git a/apps/server/src/provider/Layers/CursorProvider.ts b/apps/server/src/provider/Layers/CursorProvider.ts
--- a/apps/server/src/provider/Layers/CursorProvider.ts
+++ b/apps/server/src/provider/Layers/CursorProvider.ts
@@ -1106,13 +1106,9 @@
   readonly stampIdentity?: (snapshot: ServerProvider) => ServerProvider;
   readonly httpClient: HttpClient.HttpClient;
 }): Effect.Effect<void> => {
-  const { settings, snapshot, publishSnapshot } = input;
+  const { snapshot, publishSnapshot } = input;
   const stampIdentity = input.stampIdentity ?? ((value) => value);
 
-  if (!settings.enabled || snapshot.auth.status === "unauthenticated") {
-    return Effect.void;
-  }
-
   return enrichProviderSnapshotWithVersionAdvisory(snapshot, input.maintenanceCapabilities).pipe(
     Effect.provideService(HttpClient.HttpClient, input.httpClient),
     Effect.flatMap((enrichedSnapshot) =>

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit 9438727. Configure here.

).pipe(
if (!settings.enabled || snapshot.auth.status === "unauthenticated") {
return Effect.void;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Version advisory enrichment skipped

Low Severity

enrichCursorSnapshot returns immediately when the provider is disabled or the snapshot is unauthenticated, so it never runs enrichProviderSnapshotWithVersionAdvisory or republishes advisory metadata in those states.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9438727. Configure here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intentional. enrichCursorSnapshot is a background follow-up path, and disabled Cursor providers should not perform any background work. We also skip unauthenticated snapshots to avoid republishing advisory metadata for an unusable provider state. The regular provider check remains responsible for auth/status and model discovery when enabled.

@juliusmarminge juliusmarminge enabled auto-merge (squash) June 3, 2026 17:00
@juliusmarminge juliusmarminge merged commit d78e02c into main Jun 3, 2026
13 checks passed
@juliusmarminge juliusmarminge deleted the t3code/cursor-model-probe branch June 3, 2026 17:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant