mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-19 13:23:50 +03:00
fix(cursor): preserve native Claude effort model IDs before executor dispatch (#12838)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "Cursor API provider and the Cursor CLI passthrough"
|
||||
version: 3.8.50
|
||||
lastUpdated: 2026-08-19
|
||||
version: 3.8.51
|
||||
lastUpdated: 2026-09-05
|
||||
---
|
||||
|
||||
# Cursor API provider and the Cursor CLI passthrough
|
||||
@@ -66,6 +66,18 @@ Notes:
|
||||
- `POST /api/providers/{id}/refresh-cursor` is for the `cursor` IDE provider
|
||||
only; `cursor-api` connections have no IDE session to renew.
|
||||
|
||||
## Native model IDs and effort
|
||||
|
||||
For `cursor` / `cu` and `cursor-api` / `cua`, the shared Claude-effort normalizer
|
||||
leaves the requested model ID intact. Cursor can advertise a suffix such as
|
||||
`-low` as part of a real model ID, rather than as an OmniRoute effort alias.
|
||||
The Cursor executor preserves an exact live-catalog match; when there is no
|
||||
match, its existing model resolver owns suffix-to-parameter fallback.
|
||||
|
||||
This does not change effort normalization for direct Claude, Claude-compatible,
|
||||
or Vertex routes. Availability still depends on the selected Cursor account's
|
||||
catalog and entitlement.
|
||||
|
||||
## Cursor CLI passthrough
|
||||
|
||||
Route: `src/app/api/cursor-cli/[...path]/route.ts` →
|
||||
|
||||
@@ -38,6 +38,17 @@ export function applyClaudeEffortVariant(opts: {
|
||||
sourceFormat: string;
|
||||
}): { effectiveModel: string; log: string | null } {
|
||||
const { provider, body, sourceFormat } = opts;
|
||||
// Cursor advertises native effort-suffixed ids. Its executor resolves exact
|
||||
// live-catalog ids before applying its own suffix fallback; stripping here
|
||||
// destroys that information before the executor can see it.
|
||||
if (
|
||||
provider === "cursor" ||
|
||||
provider === "cu" ||
|
||||
provider === "cursor-api" ||
|
||||
provider === "cua"
|
||||
) {
|
||||
return { effectiveModel: opts.effectiveModel, log: null };
|
||||
}
|
||||
let effectiveModel = opts.effectiveModel;
|
||||
let log: string | null = null;
|
||||
|
||||
|
||||
@@ -10,6 +10,48 @@ import { test } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { applyClaudeEffortVariant } from "../../open-sse/handlers/chatCore/claudeEffortVariant.ts";
|
||||
import { FORMATS } from "../../open-sse/translator/formats.ts";
|
||||
import { resolveRequestedModel } from "../../open-sse/utils/cursorAgentProtobuf.ts";
|
||||
|
||||
for (const provider of ["cursor", "cu", "cursor-api", "cua"]) {
|
||||
for (const sourceFormat of [FORMATS.OPENAI, FORMATS.CLAUDE, FORMATS.OPENAI_RESPONSES]) {
|
||||
test(`${provider}/${sourceFormat}: preserves native Cursor Claude model ids before executor resolution`, () => {
|
||||
for (const model of [
|
||||
"claude-fable-5-1-low",
|
||||
"claude-fable-5-1-thinking-low",
|
||||
"claude-opus-5-low",
|
||||
]) {
|
||||
const body = { model, messages: [] };
|
||||
const result = applyClaudeEffortVariant({
|
||||
provider,
|
||||
effectiveModel: model,
|
||||
body,
|
||||
sourceFormat,
|
||||
});
|
||||
assert.deepEqual(result, { effectiveModel: model, log: null });
|
||||
assert.deepEqual(body, { model, messages: [] });
|
||||
assert.deepEqual(
|
||||
resolveRequestedModel(result.effectiveModel, { liveCatalogIds: new Set([model]) }),
|
||||
{ modelId: model, parameters: [] }
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
test("Cursor preserves explicit client effort while its encoder owns non-catalog suffix fallback", () => {
|
||||
const body = { model: "claude-opus-5-low", reasoning_effort: "none", messages: [] };
|
||||
const result = applyClaudeEffortVariant({
|
||||
provider: "cursor",
|
||||
effectiveModel: body.model,
|
||||
body,
|
||||
sourceFormat: FORMATS.OPENAI,
|
||||
});
|
||||
assert.deepEqual(body, { model: "claude-opus-5-low", reasoning_effort: "none", messages: [] });
|
||||
assert.deepEqual(resolveRequestedModel(result.effectiveModel, { liveCatalogIds: new Set() }), {
|
||||
modelId: "claude-opus-5",
|
||||
parameters: [{ id: "effort", value: "low" }],
|
||||
});
|
||||
});
|
||||
|
||||
test("claude provider + effort suffix → strips to base, mutates body model + reasoning_effort, returns log", () => {
|
||||
const body: Record<string, unknown> = { model: "claude-sonnet-4-high", messages: [] };
|
||||
|
||||
Reference in New Issue
Block a user