-
Notifications
You must be signed in to change notification settings - Fork 972
feat(cursor): opt-in effort-variant rows for models outside Cursor's effort table #3276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
80edde1
cbe92c9
6ee8917
b1592d6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -50,6 +50,10 @@ import { | |
| isTranslatorBudgetExceededError, | ||
| type TranslatorBudget, | ||
| } from "../lib/translator-budget"; | ||
| import { | ||
| parseRequestEffortRowId, | ||
| type ParsedEffortRowId, | ||
| } from "./effort-row"; | ||
|
|
||
| type Rec = Record<string, unknown>; | ||
|
|
||
|
|
@@ -600,7 +604,9 @@ async function handleClaudeMessagesWithBudget( | |
| let anthropicBody: unknown; | ||
| let internalBody: Rec; | ||
| let cacheKeySource: ClaudeCacheKeySource = null; | ||
| let effortOverride: ReturnType<typeof extractOcxEffortDirective> = null; | ||
| let effortOverride: string | null = null; | ||
| let effortRow: ParsedEffortRowId | null = null; | ||
| let requestedModel = ""; | ||
| try { | ||
| anthropicBody = await readAnthropicBody(req, translatorBudget); | ||
| // Defensive [1m] strip (devlog 138): clients normally remove the context-variant | ||
|
|
@@ -620,6 +626,14 @@ async function handleClaudeMessagesWithBudget( | |
| effortOverride = extractOcxEffortDirective(anthropicBody); | ||
| } | ||
| } | ||
| if (isRec(anthropicBody) && typeof anthropicBody.model === "string") { | ||
| requestedModel = anthropicBody.model; | ||
| effortRow = parseRequestEffortRowId(requestedModel, config); | ||
| if (effortRow) { | ||
| anthropicBody.model = effortRow.baseId; | ||
| effortOverride = effortRow.effort; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Document and test effort-row precedence. Line 626 stores the explicit effort directive. Line 634 replaces it with the effort-row value. Therefore, the effort-row selector wins when a request supplies both values. Document this precedence in As per path instructions: 🤖 Prompt for AI AgentsSource: Path instructions
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Documented in the guide PR (#3278): the effort-row selector is the user's explicit choice and wins over an
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This review thread still needs the Claude Messages regression test. The test should send both an ✏️ Learnings added
🧠 Learnings usedYou are interacting with an AI system. |
||
| } | ||
| } | ||
| // Debug capture (opt-in allowlist scalars) BEFORE the passthrough branch so | ||
| // native, routed, and disabled-alias paths are all observable (devlog 130 B1). | ||
| captureClaudeInbound( | ||
|
|
@@ -643,7 +657,7 @@ async function handleClaudeMessagesWithBudget( | |
| ); | ||
| if (claudeConversationId) logCtx.conversationId = claudeConversationId; | ||
| } | ||
| if (isRec(anthropicBody) && wantsNativePassthrough(req, config, requestPolicy, anthropicBody.model)) { | ||
| if (!effortRow && isRec(anthropicBody) && wantsNativePassthrough(req, config, requestPolicy, anthropicBody.model)) { | ||
| return await anthropicNativePassthrough(req, config, logCtx, logIds, anthropicBody, "/v1/messages"); | ||
| } | ||
| if (isRec(anthropicBody) && effortOverride) { | ||
|
|
@@ -669,7 +683,7 @@ async function handleClaudeMessagesWithBudget( | |
| ); | ||
| } | ||
|
|
||
| const requestedModel = (anthropicBody as Rec).model as string; | ||
| if (!requestedModel) requestedModel = (anthropicBody as Rec).model as string; | ||
| const stream = internalBody.stream === true; | ||
| // Routed adapters only support streamed turns; always stream internally and fold | ||
| // the translated Anthropic SSE into a message JSON for non-streaming clients. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| import { comboModelId, comboPublicModelId } from "../combos/types"; | ||
| import { detectCursorInstalls } from "../integrations/cursor-detect"; | ||
| import { | ||
| loadCursorEffortTable, | ||
| type CursorEffortTable, | ||
| } from "../integrations/cursor-effort-table"; | ||
| import { | ||
| canonicalizeReasoningEfforts, | ||
| isDeclaredReasoningEffort, | ||
| } from "../reasoning-effort"; | ||
| import { knownModelIdsForProvider } from "../router"; | ||
| import { policyModelId, policyPublicModelId } from "../routing/profile"; | ||
| import type { OcxConfig } from "../types"; | ||
| import { routedSlug } from "../providers/slug-codec"; | ||
| import { predictCursorEffort } from "./models-capabilities"; | ||
|
|
||
| const EFFORT_ROW_SEPARATOR = "--"; | ||
|
|
||
| export interface ParsedEffortRowId { | ||
| baseId: string; | ||
| effort: string; | ||
| } | ||
|
|
||
| export type EffortRowKnownIds = ReadonlySet<string> | ((id: string) => boolean); | ||
|
|
||
| export interface EffortRowOptions { | ||
| knownIds?: EffortRowKnownIds; | ||
| table?: CursorEffortTable | null; | ||
| supportsReasoning?: boolean; | ||
| } | ||
|
|
||
| function isKnownId(knownIds: EffortRowKnownIds | undefined, id: string): boolean { | ||
| return typeof knownIds === "function" ? knownIds(id) : knownIds?.has(id) === true; | ||
| } | ||
|
|
||
| export function effortRowId(baseId: string, effort: string): string { | ||
| return `${baseId}${EFFORT_ROW_SEPARATOR}${effort}`; | ||
| } | ||
|
|
||
| /** | ||
| * Exact configured/public ids that must beat the synthetic terminal-suffix grammar. | ||
| * This is request-local because live-model cache contents can change while the server runs. | ||
| */ | ||
| export function knownEffortRowIds(config: OcxConfig): Set<string> { | ||
| const ids = new Set<string>(); | ||
| for (const [providerName, provider] of Object.entries(config.providers)) { | ||
| const known = knownModelIdsForProvider(providerName, provider, config); | ||
| const namespaces = [providerName, provider.alias].filter((value): value is string => ( | ||
| typeof value === "string" && value.length > 0 | ||
| )); | ||
| for (const id of known) { | ||
| ids.add(id); | ||
| ids.add(routedSlug(providerName, id)); | ||
| for (const namespace of namespaces) ids.add(`${namespace}/${id}`); | ||
| } | ||
| for (const alias of Object.values(provider.modelAliases ?? {})) { | ||
| ids.add(alias); | ||
| for (const namespace of namespaces) ids.add(`${namespace}/${alias}`); | ||
| } | ||
| } | ||
| for (const [id, combo] of Object.entries(config.combos ?? {})) { | ||
| ids.add(comboModelId(id)); | ||
| ids.add(comboPublicModelId(id, combo)); | ||
| } | ||
| for (const [id, profile] of Object.entries(config.routingProfiles ?? {})) { | ||
| ids.add(policyModelId(id)); | ||
| ids.add(policyPublicModelId(id, profile)); | ||
| } | ||
| return ids; | ||
| } | ||
|
|
||
| /** Resolve the installed Private Inference effort table once for the current request. */ | ||
| export function loadDetectedCursorEffortTable(): CursorEffortTable | null { | ||
| const privateInference = detectCursorInstalls().find(install => install.build === "private-inference"); | ||
| return loadCursorEffortTable(privateInference); | ||
| } | ||
|
|
||
| export function parseEffortRowId( | ||
| id: string, | ||
| config: Pick<OcxConfig, "cursorEffortRows">, | ||
| options: EffortRowOptions = {}, | ||
| ): ParsedEffortRowId | null { | ||
| if (config.cursorEffortRows !== true || isKnownId(options.knownIds, id)) return null; | ||
|
|
||
| const separator = id.lastIndexOf(EFFORT_ROW_SEPARATOR); | ||
| if (separator <= 0) return null; | ||
| const baseId = id.slice(0, separator); | ||
| const effort = id.slice(separator + EFFORT_ROW_SEPARATOR.length); | ||
| // "none" is never published as a row (discovery filters it), so it is never accepted either. | ||
| if (effort === "none" || !isDeclaredReasoningEffort(effort)) return null; | ||
| if (predictCursorEffort(baseId, options.table ?? null, options.supportsReasoning).ladder !== null) { | ||
| return null; | ||
| } | ||
| return { baseId, effort }; | ||
| } | ||
|
|
||
| /** Parse one ingress selector against the current config and installed Cursor table. */ | ||
| export function parseRequestEffortRowId(id: string, config: OcxConfig): ParsedEffortRowId | null { | ||
| if (config.cursorEffortRows !== true) return null; | ||
| // Ordinary ids carry no separator; bail before the known-id scan and install detection so | ||
| // the flag costs nothing on the request path for models that are not effort rows. | ||
| if (id.lastIndexOf(EFFORT_ROW_SEPARATOR) <= 0) return null; | ||
| return parseEffortRowId(id, config, { | ||
| knownIds: knownEffortRowIds(config), | ||
| table: loadDetectedCursorEffortTable(), | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| }); | ||
| } | ||
|
|
||
| export function expandCursorEffortRow<T extends { id: string }>( | ||
| row: T, | ||
| efforts: readonly string[] | undefined, | ||
| config: Pick<OcxConfig, "cursorEffortRows">, | ||
| options: EffortRowOptions = {}, | ||
| ): T[] { | ||
| if (config.cursorEffortRows !== true) return [row]; | ||
|
|
||
| const supported = canonicalizeReasoningEfforts( | ||
| (efforts ?? []).filter(effort => effort !== "none" && isDeclaredReasoningEffort(effort)), | ||
| ); | ||
| const supportsReasoning = options.supportsReasoning ?? supported.length > 0; | ||
| if (predictCursorEffort(row.id, options.table ?? null, supportsReasoning).ladder !== null) { | ||
| return [row]; | ||
| } | ||
| return [ | ||
| row, | ||
| ...supported | ||
| .map(effort => effortRowId(row.id, effort)) | ||
| .filter(id => !isKnownId(options.knownIds, id)) | ||
| .map(id => ({ ...row, id })), | ||
| ]; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.