Summary
Importing a local Cursor subscription exposes cursor/grok-4.5 in OpenCodex, but requests fail with:
stream disconnected before completion: Cursor 流结束错误:Model name is not valid: "grok-4.5"
The Cursor subscription and authentication are valid. The failure is caused by OpenCodex sending the imported base slug grok-4.5 directly as the Cursor AgentService modelId, while Cursor Agent CLI requires an effort-qualified selector such as cursor-grok-4.5-high.
Environment
- macOS, Apple Silicon
- OpenCodex 1.1.1 installed locally
- Cursor Agent
2026.07.23-e383d2b
- Cursor Desktop
3.14.7
- The same relevant code is still present in OpenCodex v1.1.2 / current
master (20b73d09)
Steps to reproduce
- Import a local Cursor subscription in OpenCodex.
- The provider test succeeds and reports that Cursor models were fetched.
- Select
cursor/grok-4.5 with reasoning effort high.
- Send any prompt through Codex Desktop /
/v1/responses.
- The stream ends with
Model name is not valid: "grok-4.5".
Cursor model IDs reported for this account
cursor-agent --list-models reports these valid Grok selectors:
cursor-grok-4.5-low
cursor-grok-4.5-low-fast
cursor-grok-4.5-medium
cursor-grok-4.5-medium-fast
cursor-grok-4.5-high
cursor-grok-4.5-high-fast
It does not report a bare grok-4.5 selector.
Root cause
The imported catalog entry is effectively:
{
"slug": "cursor/grok-4.5",
"backend_model": "grok-4.5",
"backend_provider": "cursor",
"default_reasoning_level": "medium"
}
The routing path does not combine the backend model with the selected reasoning effort:
router.ts assigns cursorModelForRequest = ... || upstreamModel.
router.ts passes that value directly to streamCursorChat.
cursor_protocol.ts writes it directly into ModelDetails.modelId.
As a result, modelId is grok-4.5, and the separately selected reasoning_effort=high never becomes part of Cursor's required model selector.
The current provider test only proves that AvailableModels can be fetched, so it reports a healthy Cursor subscription even though an actual AgentService generation request fails.
Verified local workaround
Changing only the imported catalog entry to:
"backend_model": "cursor-grok-4.5-high"
made the same local /v1/responses request complete successfully with response.completed. This workaround may be overwritten when models are re-imported.
Suggested fix
-
Normalize Cursor AgentService model selectors before streamCursorChat, using the selected reasoning effort. For this model:
grok-4.5 + low -> cursor-grok-4.5-low
grok-4.5 + medium -> cursor-grok-4.5-medium
grok-4.5 + high -> cursor-grok-4.5-high
-
Prefer preserving or deriving AgentService-valid IDs from Cursor's actual CLI/model metadata instead of assuming the imported base slug is directly callable.
-
Add an end-to-end provider test that performs a minimal AgentService generation, rather than only fetching the model catalog.
-
Add a regression test asserting that cursor/grok-4.5 with high effort sends modelId=cursor-grok-4.5-high.
Expected behavior
Selecting cursor/grok-4.5 should generate a valid Cursor AgentService model selector from the chosen effort and complete the response normally.
Summary
Importing a local Cursor subscription exposes
cursor/grok-4.5in OpenCodex, but requests fail with:The Cursor subscription and authentication are valid. The failure is caused by OpenCodex sending the imported base slug
grok-4.5directly as the Cursor AgentServicemodelId, while Cursor Agent CLI requires an effort-qualified selector such ascursor-grok-4.5-high.Environment
2026.07.23-e383d2b3.14.7master(20b73d09)Steps to reproduce
cursor/grok-4.5with reasoning efforthigh./v1/responses.Model name is not valid: "grok-4.5".Cursor model IDs reported for this account
cursor-agent --list-modelsreports these valid Grok selectors:It does not report a bare
grok-4.5selector.Root cause
The imported catalog entry is effectively:
{ "slug": "cursor/grok-4.5", "backend_model": "grok-4.5", "backend_provider": "cursor", "default_reasoning_level": "medium" }The routing path does not combine the backend model with the selected reasoning effort:
router.tsassignscursorModelForRequest = ... || upstreamModel.router.tspasses that value directly tostreamCursorChat.cursor_protocol.tswrites it directly intoModelDetails.modelId.As a result,
modelIdisgrok-4.5, and the separately selectedreasoning_effort=highnever becomes part of Cursor's required model selector.The current provider test only proves that
AvailableModelscan be fetched, so it reports a healthy Cursor subscription even though an actual AgentService generation request fails.Verified local workaround
Changing only the imported catalog entry to:
made the same local
/v1/responsesrequest complete successfully withresponse.completed. This workaround may be overwritten when models are re-imported.Suggested fix
Normalize Cursor AgentService model selectors before
streamCursorChat, using the selected reasoning effort. For this model:Prefer preserving or deriving AgentService-valid IDs from Cursor's actual CLI/model metadata instead of assuming the imported base slug is directly callable.
Add an end-to-end provider test that performs a minimal AgentService generation, rather than only fetching the model catalog.
Add a regression test asserting that
cursor/grok-4.5withhigheffort sendsmodelId=cursor-grok-4.5-high.Expected behavior
Selecting
cursor/grok-4.5should generate a valid Cursor AgentService model selector from the chosen effort and complete the response normally.