-
Notifications
You must be signed in to change notification settings - Fork 1.2k
fix(models): mirror model capacity onto the /v1/models top level #4889
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
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 |
|---|---|---|
|
|
@@ -10,6 +10,11 @@ import type { CursorEffortTable } from "../integrations/cursor-effort-table"; | |
| * Completions, Responses and Anthropic Messages, streams, and accepts tool calls, so those are | ||
| * constants; context length and vision come from catalog data when known and are omitted | ||
| * otherwise, matching Cursor's optional-field schema. | ||
| * | ||
| * Top-level capacity metrics (`context_window`, `context_length`, `max_output_tokens`) are | ||
| * mirrored directly on each model row for external client discovery (e.g. pi-ai, DSH, | ||
| * LibreChat) that inspects flat properties rather than Cursor's nested `capabilities.*` shape. | ||
| * A row that gains a nested capacity value must gain the top-level mirror in the same change. | ||
|
Comment on lines
+14
to
+17
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 changes the user-facing plain AGENTS.md reference: AGENTS.md:L380-L381 Useful? React with 👍 / 👎. |
||
| */ | ||
|
|
||
| /** | ||
|
|
@@ -132,6 +137,19 @@ export interface ModelCapabilityFields { | |
| supports_vision?: boolean; | ||
| reasoning_effort?: string[]; | ||
| }; | ||
| /** | ||
| * Mirrored top-level context window for external/legacy client discovery (e.g. pi-ai, DSH) | ||
| * that reads top-level context_window / context_length instead of nested capabilities. | ||
| */ | ||
| context_window?: number; | ||
| /** | ||
| * Top-level context length alias matching capabilities.context_length for clients expecting context_length. | ||
| */ | ||
| context_length?: number; | ||
| /** | ||
| * Mirrored top-level max output token limit for external/legacy client discovery. | ||
| */ | ||
| max_output_tokens?: number; | ||
| /** | ||
| * Cursor reads the long-context threshold from `pricing.overrides[].min_prompt_tokens`. That | ||
| * key sits outside its validated capability schema, so it is the one place a threshold can | ||
|
|
@@ -153,16 +171,15 @@ export function modelCapabilityFields(input: ModelCapabilityInput): ModelCapabil | |
| const longContextLength = positiveInt(input.longContextWindow); | ||
| const maxOutputTokens = positiveInt(input.maxOutputTokens); | ||
| const hasLongTier = contextLength !== undefined && longContextLength !== undefined && longContextLength > contextLength; | ||
| const effectiveContextLength = hasLongTier ? longContextLength : contextLength; | ||
| const modalities = Array.isArray(input.inputModalities) | ||
| ? input.inputModalities.filter(modality => typeof modality === "string" && modality.length > 0) | ||
| : undefined; | ||
| const supportsVision = modalities !== undefined ? modalities.includes("image") : undefined; | ||
| return { | ||
| api_types: [...OPENCODEX_MODEL_API_TYPES], | ||
| capabilities: { | ||
| ...(hasLongTier | ||
| ? { context_length: longContextLength } | ||
| : contextLength !== undefined ? { context_length: contextLength } : {}), | ||
| ...(effectiveContextLength !== undefined ? { context_length: effectiveContextLength } : {}), | ||
| ...(maxOutputTokens !== undefined ? { max_output_tokens: maxOutputTokens } : {}), | ||
| // Once a gateway advertises api_types, Cursor keeps only rows whose output_modalities | ||
| // include "text"; omitting the key drops the row from the extended catalog. | ||
|
|
@@ -174,6 +191,10 @@ export function modelCapabilityFields(input: ModelCapabilityInput): ModelCapabil | |
| ...(supportsVision !== undefined ? { supports_vision: supportsVision } : {}), | ||
| ...(efforts.length > 0 ? { reasoning_effort: [...efforts] } : {}), | ||
| }, | ||
| ...(effectiveContextLength !== undefined | ||
| ? { context_window: effectiveContextLength, context_length: effectiveContextLength } | ||
| : {}), | ||
| ...(maxOutputTokens !== undefined ? { max_output_tokens: maxOutputTokens } : {}), | ||
| ...(hasLongTier ? { pricing: { overrides: [{ min_prompt_tokens: contextLength }] } } : {}), | ||
| }; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -180,6 +180,10 @@ then trusted catalog metadata such as a configured qualified provider/model alia | |
| This overlay never changes route identity or the upstream wire model, and its catalog fingerprint makes | ||
| a label edit refresh Codex output. | ||
|
|
||
| Raw `/v1/models` rows advertise positive safe capacity values in both Cursor's nested | ||
| `capabilities` object and top-level discovery fields used by other clients. A model with a larger | ||
| opt-in context tier uses that effective long window in both shapes; invalid values are omitted. | ||
|
Comment on lines
+183
to
+185
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.
Only AGENTS.md reference: structure/AGENTS.md:L44-L50 Useful? React with 👍 / 👎. |
||
|
|
||
| Supported bare native GPT rows also consume `providers.openai.modelDisplayNames`. Retained sync | ||
| and convergence pass the same map to the observed-state merge. After native normalization and | ||
| ordering, the merge applies the exact nonblank trimmed label and saves | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The commit explicitly says this continues #4802 by @Yum-wu and claims the
Co-authored-bytrailer is present, but the raw commit contains no such trailer; the prose mention does not give the contributor attribution. Add the required trailer to the PR description or a branch commit so it survives the squash.AGENTS.md reference: AGENTS.md:L288-L292
Useful? React with 👍 / 👎.