Skip to content

fix(cursor): support ACP parameterized model picker for Composer 2.5 non-fast #968

Description

@swear01

What issue are you seeing?

Cursor remote sessions in HAPI cannot reliably select the non-fast/general Composer 2.5 variant via ACP.

New Session can display user-facing Cursor CLI SKUs such as:

Composer 2.5
Composer 2.5 Fast

But selecting Composer 2.5 can still create an active Cursor session that reports/runs as:

composer-2.5[fast=true]

That means the non-fast selection silently becomes Fast.

Current observed behavior

Cursor CLI lists both SKUs:

agent --list-models
composer-2.5      - Composer 2.5
composer-2.5-fast - Composer 2.5 Fast (default)

But with HAPI's current ACP initialize capabilities, Cursor ACP exposes only the exploded fast wire for Composer 2.5:

currentModelId composer-2.5[fast=true]
available composer [ "composer-2.5[fast=true]" ]
model config options [ "composer-2.5[fast=true]" ]

Trying to set the missing exploded non-fast wire directly fails:

setConfigOption("composer-2.5[fast=false]") -> Invalid params

So HAPI currently cannot apply Composer 2.5 non-fast through the exploded-wire ACP mode.

Root cause

HAPI does not advertise Cursor's parameterized model picker capability during ACP initialize.

Current HAPI initialize shape is roughly:

clientCapabilities: {
    fs: { readTextFile: false, writeTextFile: false },
    terminal: false
}

Other ACP client investigations show Cursor has a parameterized model picker mode. When the client advertises:

{
  "clientCapabilities": {
    "_meta": {
      "parameterizedModelPicker": true
    }
  }
}

Cursor can expose the Composer choice as separate config options instead of only exploded model strings:

model = composer-2.5
fast  = false | true

In that mode:

Composer 2.5      => model=composer-2.5 + fast=false
Composer 2.5 Fast => model=composer-2.5 + fast=true

HAPI currently expects model variants mostly as a single model config value such as composer-2.5[fast=true], so it misses the ACP-native way to select non-fast Composer 2.5.

Upstream / external context

Relation to #883/#887

This is separate from #883/#887.

#887 fixed the exploded-wire case where ACP exposes both:

composer-2.5[fast=true]
composer-2.5[fast=false]

and HAPI needs to map:

composer-2.5      -> composer-2.5[fast=false]
composer-2.5-fast -> composer-2.5[fast=true]

This issue is about HAPI not requesting/supporting Cursor's parameterized model picker mode, where the correct ACP representation is:

model=composer-2.5 + fast=false/true

Desired behavior

Keep the frontend display close to Cursor CLI / old HAPI UX:

Composer 2.5
Composer 2.5 Fast

But apply the selection through ACP correctly:

  • Composer 2.5 applies model=composer-2.5 and fast=false
  • Composer 2.5 Fast applies model=composer-2.5 and fast=true
  • HAPI never silently maps Composer 2.5 to composer-2.5[fast=true]

Proposed fix direction

1. ACP initialize

Advertise Cursor-compatible parameterized model picker support:

clientCapabilities: {
    fs: { readTextFile: false, writeTextFile: false },
    terminal: false,
    _meta: {
        parameterizedModelPicker: true
    }
}

Prefer gating to Cursor ACP if needed; otherwise unknown _meta should be safe for agents that ignore it.

2. Capture parameterized config options

Teach HAPI to preserve and expose Cursor config options beyond only the model exploded-wire option, especially options like:

model: currentValue composer-2.5, options [...]
fast:  currentValue false|true, options false|true

3. Resolve CLI SKUs to ACP config patches

Support applying Cursor CLI SKUs as multi-option config patches:

composer-2.5      => set model=composer-2.5; set fast=false
composer-2.5-fast => set model=composer-2.5; set fast=true

Keep existing exploded-wire support as compatibility for ACP responses that still expose full wire IDs.

4. UI/catalog

Back each visible variant row with one of:

  1. exact exploded ACP wire, or
  2. parameterized ACP config patch (model + fast, etc.)

If neither exists, do not silently coerce to another variant.

5. Active composer UI regression

Main currently has a separate UI regression from #862: HappyComposer.tsx still computes showModelEffortSettings, modelEffortOptions, and selectedModelVariant, but the render block for the Cursor Variant section was removed. Restore it so in-session Cursor Variant switching is visible again.

Acceptance criteria

  1. HAPI ACP initialize advertises parameterized model picker support for Cursor.
  2. Cursor ACP responses with separate model and fast config options are parsed and stored.
  3. New Session selecting Composer 2.5 creates/runs a session with fast=false, not fast=true.
  4. New Session selecting Composer 2.5 Fast creates/runs a session with fast=true.
  5. If Cursor returns exploded wires, fix(cursor): map base-only CLI sku to fast=false (closes #883) #887 behavior remains intact.
  6. HAPI never silently maps a non-fast CLI SKU to a fast ACP variant.
  7. In-session Cursor Variant picker is visible again in HappyComposer.tsx.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:cursorCursor flavorarea:cliCLI, runner, agent wrappersarea:webWeb PWA / React clientbugSomething isn't workingstatus:pr-openFix PR open

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions