fix(cursor): send composer fast mode as model metadata, not a model id - #411
fix(cursor): send composer fast mode as model metadata, not a model id#411r-uben wants to merge 3 commits into
Conversation
`cursor-agent models` advertises `composer-2.5-fast`, but the AgentService answered `not_found` for it: shunt passed the picker name through as the wire model id. Capturing what the official CLI sends for `--model composer-2.5-fast` shows it transmits the base name `composer-2.5` with `fast=true` model metadata, in both the selected model (field 9) and the catalog entry (field 14) -- `fast` is a model parameter, not part of the id. Resolve `composer-2.5-fast` and the parameterized `composer-2.5[fast=true]` / `[fast=false]` forms to the `composer-2.5` wire id plus a `fast` flag, and carry that flag through to both `encode_model_meta` call sites. The legacy bare names keep their existing mode mapping. Verified against the live upstream: before, `cursor:composer-2.5` -> 200 and `cursor:composer-2.5-fast` -> 502 not_found; after, the base, `-fast`, and `[fast=true]` forms all return 200.
There was a problem hiding this comment.
Code Review
This pull request introduces support for Cursor's parameterized composer-2.5-fast model alias and its explicit [fast=true/false] variants. The model resolution logic in src/adapters/cursor/model.rs has been updated to map these aliases to the base composer-2.5 wire ID while extracting a new fast boolean flag. This flag is propagated through AgentRunParams and encoded into the request frames. Comprehensive unit tests, benchmarks, and multi-language documentation have been updated accordingly. No review comments were provided, and the implementation is clean, well-tested, and adheres to the project's standards; therefore, I have no additional feedback to provide.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f2fa9ae593
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| Cursor's `composer-2.5-fast` picker entry is a parameterized alias rather than a wire id. Route | ||
| `cursor:composer-2.5-fast` (or `cursor:composer-2.5[fast=true]`) and shunt sends the | ||
| `composer-2.5` wire id with `fast=true` model metadata, matching the official CLI. |
There was a problem hiding this comment.
Add the localized Cursor provider pages
This user-facing model behavior is added only to the English site page. A repo-wide search of site/src/content/docs/{ko,ja,zh-cn} finds no corresponding providers/cursor.mdx files, so the maintained site translations do not receive the new alias and metadata instructions. Add the Korean, Japanese, and Simplified Chinese copies alongside this change.
AGENTS.md reference: AGENTS.md:L57-L64
Useful? React with 👍 / 👎.
Greptile SummaryThe PR normalizes the supported Cursor Composer fast aliases to the
Confidence Score: 5/5The PR appears safe to merge because no blocking failure remains. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| src/adapters/cursor/model.rs | Adds exact Composer alias normalization and a fast-mode value while preserving the existing mode selection behavior. |
| src/adapters/cursor/agent.rs | Propagates fast mode consistently to selected-model and catalog metadata and tests both boolean values. |
| src/adapters/cursor/mod.rs | Connects the resolved fast-mode value to production request construction. |
| site/src/content/docs/providers/cursor.mdx | Documents the Composer fast alias and its base-ID-plus-metadata wire representation. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
Input[Cursor model selection] --> Resolve{Recognized Composer fast alias?}
Resolve -->|Yes| Base[Wire ID: composer-2.5]
Resolve -->|No| Original[Keep original wire ID]
Base --> Metadata[Encode fast metadata]
Original --> Default[Encode fast=false metadata]
Metadata --> Selected[Selected model field 9]
Metadata --> Catalog[Catalog entry field 14]
Default --> Selected
Default --> Catalog
Reviews (2): Last reviewed commit: "Merge branch 'main' into fix/cursor-comp..." | Re-trigger Greptile
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
No issues found across 9 files
Architecture diagram
sequenceDiagram
participant Client as Client Application
participant Resolver as Cursor Model Resolver
participant Agent as Cursor Agent Adapter
participant Gateway as Shunt Gateway
participant API as Cursor AgentService API
Note over Client,API: Cursor Composer Model Resolution and Encoding Flow
Client->>Resolver: resolve_cursor_model("cursor:composer-2.5-fast")
alt Suffix-prefixed form (cursor:<id>)
Resolver->>Resolver: Extract rest = "composer-2.5-fast"
Resolver->>Resolver: Look up in CURSOR_MODEL_ALIASES
alt Alias found (composer-2.5-fast / [fast=true] / [fast=false])
Resolver-->>Client: CursorModelResolution(model_id="composer-2.5", fast=true/false)
else No alias match
Resolver-->>Client: CursorModelResolution(model_id=original, fast=false)
end
else Legacy bare name
Resolver->>Resolver: Match legacy mapping (e.g. composer-2.5-fast)
Resolver->>Resolver: Check CURSOR_MODEL_ALIASES
Resolver-->>Client: CursorModelResolution(wire_id + fast flag)
end
Client->>Agent: AgentRunParams(model_id, fast, mode)
Note over Agent: build_run_frames() constructs wire frames
Agent->>Agent: Encode frame fields
Note right of Agent: Field 9: selected model<br/>Field 14: catalog entry
Agent->>Agent: encode_model_meta(model_id, fast)
Agent->>Agent: Field 9 = encode_model_meta("composer-2.5", fast)
Agent->>Agent: Field 14 = encode_model_meta("composer-2.5", fast)
Agent->>Gateway: Send connect frame with encoded model metadata
Gateway->>API: Forward Cursor AgentService request
alt Successful resolution
API-->>Gateway: 200 OK (composer-2.5 with fast metadata)
Gateway-->>Agent: Stream response
Agent-->>Client: Assistant text/reasoning
else Unresolved model (e.g. cursor:composer-2.5-fast sent as wire id)
API-->>Gateway: 502 not_found (composer-2.5-fast)
Gateway-->>Client: Error response
end
Note over API: Legacy behavior preserved:<br/>bare composer-2.5 -> PLAN mode<br/>bare composer-2.5-fast -> ASK mode
# Conflicts: # README.ja.md # README.ko.md # README.zh-CN.md
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Summary
cursor-agent modelsadvertisescomposer-2.5-fast, but shunt returnedConnect error 502 (not_found)forcursor:composer-2.5-fastwhilecursor:composer-2.5worked. shunt was passing the picker name straight through as the wire model id.Capturing what the official
cursor-agentCLI sends for--model composer-2.5-fastshows it transmits the base namecomposer-2.5together withfast=truemodel metadata — in both the selected model (field 9) and the catalog entry (field 14).fastis a model parameter, not part of the id. The CLI hints at this itself: it documents parameterized overrides such as--model 'claude-opus-4-8[context=1m,effort=high,fast=false]'.This resolves
composer-2.5-fastand the parameterizedcomposer-2.5[fast=true]/[fast=false]forms to thecomposer-2.5wire id plus afastflag, and carries that flag to bothencode_model_metacall sites. Legacy bare names keep their existing mode mapping.Verification
Against the live upstream, isolated gateway on its own port:
cursor:composer-2.5cursor:composer-2.5-fastcursor:composer-2.5[fast=true]A unit test asserts the metadata is encoded in both the selected-model and catalog positions, and pins
fast=falseas well asfast=trueso a constant-true regression cannot pass.Milestone / spec
None — a wire-encoding bug in the
agent.v1Cursor path.Checklist
cargo buildpassescargo testpasses (1693 passed, 0 failed; run independently of the author)cargo clippy --all-targets --all-features -- -D warningscleancargo fmt --all --checkcleanmodel.rsis 260 lines;agent.rswas already oversized before this change, tracked by Split oversized Cursor adapter files (>500 lines) into focused modules #59)docs/updated if this change deviates from it (n/a)site/src/content/docs/providers/cursor.mdxplusREADME.mdand itsja/ko/zh-CNtranslationsNotes for reviewers
[context=1m,effort=high,fast=false]) was not attempted, because only thefastencoding was confirmed by capture.-fastvariants (cursor-grok-4.6-high-fast,claude-opus-5-thinking-high-fast, …). These are not covered here. On the test accountcursor-grok-4.6-highfails withnot_foundat the base id too, so whether-fasthandling generalizes to them could not be evaluated — it may need a different id namespace or an entitlement this account lacks.composer-2.5→ PLAN,composer-2.5-fast→ ASK) are pre-existing compatibility behavior and intentionally unchanged.Summary by cubic
Fixes Cursor Composer fast mode routing by sending the base model id with a fast flag instead of a separate wire id. Previously
cursor:composer-2.5-fastreturned 502 not_found; now we sendcomposer-2.5withfast=truein both the selected model and catalog entries, matching the official CLI.Bug Fixes
composer-2.5-fastandcomposer-2.5[fast=true|false]tocomposer-2.5plus afastflag.fastthroughAgentRunParamsto metadata encoding at fields 9 and 14; default isfast=false.Migration
AgentRunParams, add the newfast: boolfield (set false unless you need fast mode).Written for commit 1864a4b. Summary will update on new commits.