Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/adapters/cursor/discovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ export const CURSOR_STATIC_MODELS: readonly CursorModelInfo[] = normalizeCursorM

{ id: "grok-4.5", contextWindow: 500_000, supportsReasoningEffort: true },
{ id: "grok-4.5-fast", contextWindow: 500_000, supportsReasoningEffort: true },
// 260813 preemptive: grok-4.6 seeded ahead of Cursor's lineup update (mirrors grok-4.5).
// 260812: xAI launched Grok 4.6 in Cursor; account-verified with cursor-grok-4.6-high.
{ id: "grok-4.6", contextWindow: 500_000, supportsReasoningEffort: true },
{ id: "grok-4.6-fast", contextWindow: 500_000, supportsReasoningEffort: true },
]);
Expand Down
5 changes: 3 additions & 2 deletions src/adapters/cursor/effort-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ const CURSOR_MODEL_EFFORT_TIERS: Record<string, readonly string[]> = {
// cursor-grok-4.5-{low,medium,high}-fast. The bare Fast id returns not_found.
"grok-4.5": ["low", "medium", "high"],
"grok-4.5-fast": ["low", "medium", "high"],
// 260813 preemptive: grok-4.6 tiers mirrored from grok-4.5 ahead of Cursor's lineup update,
// so the suffix/wire handling is already correct the day the slugs appear.
// 260812: cursor-grok-4.6-high is the only tier account-verified on the wire. low/medium are
// the effort ladder announced for the Cursor launch, not separately recorded wire evidence.
// The parameterized Fast variant is inherited from the grok-4.5 encoding, not new verification.
"grok-4.6": ["low", "medium", "high"],
"grok-4.6-fast": ["low", "medium", "high"],
"gpt-5.1": ["low", "high"],
Expand Down
19 changes: 19 additions & 0 deletions tests/cursor-discovery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ describe("Cursor discovery metadata", () => {
expect(ids).toContain("kimi-k2.7-code");
expect(ids).toContain("kimi-k3");
expect(ids).toContain("claude-opus-4-7-fast");
expect(ids).toContain("grok-4.6");
expect(ids).toContain("grok-4.6-fast");
// 260709 refresh: stale ids dropped from the static seed (cursor.com docs); gpt-5.5-extra
// stays — it survives the live GetUsableModels filter (004_live_snapshot.md).
expect(ids).not.toContain("grok-4.20");
Expand Down Expand Up @@ -86,6 +88,17 @@ describe("Cursor discovery metadata", () => {
["cursor-grok-4.5-high", "cursor-grok-4.5-high-fast"],
);
expect(grok.map(model => model.id)).toEqual(["grok-4.5", "grok-4.5-fast"]);

expect(isCursorModelAvailableForAccount("grok-4.6", ["cursor-grok-4.6-high"])).toBe(true);
expect(isCursorModelAvailableForAccount("grok-4.6-fast", ["cursor-grok-4.6-low-fast"])).toBe(true);
expect(isCursorModelAvailableForAccount("grok-4.6-fast", ["cursor-grok-4.6-fast-medium"])).toBe(true);
expect(isCursorModelAvailableForAccount("grok-4.6-fast", ["cursor-grok-4.6-high"])).toBe(false);
expect(isCursorModelAvailableForAccount("grok-4.6", ["cursor-grok-4.6-high-fast"])).toBe(false);
const grok46 = filterCursorConfiguredModelsByLiveDiscovery(
[{ id: "grok-4.6" }, { id: "grok-4.6-fast" }],
["cursor-grok-4.6-high", "cursor-grok-4.6-high-fast"],
);
expect(grok46.map(model => model.id)).toEqual(["grok-4.6", "grok-4.6-fast"]);
});

test("live discovery filter always keeps all router levels when GetUsableModels omits them", () => {
Expand Down Expand Up @@ -130,6 +143,8 @@ describe("Cursor discovery metadata", () => {
expect(inferCursorContextWindow("gemini-3.5-flash")).toBe(1_000_000);
expect(inferCursorContextWindow("glm-5.2")).toBe(1_000_000);
expect(inferCursorContextWindow("grok-4.3")).toBe(256_000);
expect(inferCursorContextWindow("grok-4.6")).toBe(500_000);
expect(inferCursorContextWindow("grok-4.6-fast")).toBe(500_000);
expect(inferCursorContextWindow("gpt-5.5")).toBe(272_000);
});

Expand All @@ -148,6 +163,8 @@ describe("Cursor discovery metadata", () => {
{ id: "claude-opus-4-8", supportsReasoningEffort: true },
{ id: "glm-5.2", supportsReasoningEffort: true },
{ id: "grok-4.3", supportsReasoningEffort: true },
{ id: "grok-4.6", supportsReasoningEffort: true },
{ id: "grok-4.6-fast", supportsReasoningEffort: true },
{ id: "unknown-reasoning-model", supportsReasoningEffort: true },
{ id: "composer-2.5", supportsReasoningEffort: false },
]);
Expand All @@ -157,6 +174,8 @@ describe("Cursor discovery metadata", () => {
expect(efforts["claude-opus-4-8"]).toEqual(["low", "medium", "high", "xhigh", "max"]);
expect(efforts["glm-5.2"]).toEqual(["high", "max"]);
expect(efforts["grok-4.3"]).toEqual([]);
expect(efforts["grok-4.6"]).toEqual(["low", "medium", "high"]);
expect(efforts["grok-4.6-fast"]).toEqual(["low", "medium", "high"]);
expect(efforts["unknown-reasoning-model"]).toEqual([]);
expect(efforts["composer-2.5"]).toEqual([]);
});
Expand Down
47 changes: 47 additions & 0 deletions tests/cursor-effort-suffix.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ const RECORDED_CURSOR_GROK_45_DISCOVERY_IDS = [
"cursor-grok-4.5-high",
] as const;

// Account-verified by a successful Cursor Agent run on the 2026-08-12 launch day.
Comment thread
iamsupersocks marked this conversation as resolved.
// Only cursor-grok-4.6-high was confirmed on the wire that day; low/medium are the
// announced Cursor launch ladder, not recorded wire evidence (covered separately below).
const RECORDED_CURSOR_GROK_46_DISCOVERY_IDS = [
"cursor-grok-4.6-high",
] as const;

function modelIdFor(modelId: string, reasoning?: string): string {
const parsed: OcxParsedRequest = {
modelId,
Expand Down Expand Up @@ -135,6 +142,46 @@ describe("Cursor per-model reasoning-effort suffix", () => {
}
});

test("cursor-grok-4.6-high matches the account-verified wire id", () => {
const requestModelId = modelIdFor("cursor/grok-4.6", "high");
expect(requestModelId).toBe("cursor-grok-4.6-high");
expect(RECORDED_CURSOR_GROK_46_DISCOVERY_IDS).toContain(requestModelId);
});

// Announced Cursor launch ladder, not recorded wire evidence: only -high was observed on the
// wire (see RECORDED_CURSOR_GROK_46_DISCOVERY_IDS). This pins the request mapping for the
// low/medium tiers as announced, without claiming they were captured from a live run.
test("grok-4.6 maps the announced low/medium/high effort ladder", () => {
expect(modelIdFor("cursor/grok-4.6", "low")).toBe("cursor-grok-4.6-low");
expect(modelIdFor("cursor/grok-4.6", "medium")).toBe("cursor-grok-4.6-medium");
expect(modelIdFor("cursor/grok-4.6", "xhigh")).toBe("cursor-grok-4.6-high");
expect(modelIdFor("cursor/grok-4.6")).toBe("cursor-grok-4.6-high");
expect(cursorModelEffortLadder("grok-4.6")).toEqual(["low", "medium", "high"]);
expect(cursorModelEffortLadder("grok-4.6-fast")).toEqual(["low", "medium", "high"]);
});

// Inherited Fast request encoding: grok-4.6-fast parameterizes exactly like grok-4.5-fast
// (base id + effort/fast requested_model parameters) rather than a flat suffixed id. This
// mirrors the sibling grok-4.5 behavior; it is not separately verified wire evidence.
test("grok-4.6-fast inherits the parameterized Fast encoding", () => {
expect(selectionFor("cursor/grok-4.6-fast", "low")).toEqual({
modelId: "grok-4.6",
parameters: [{ id: "effort", value: "low" }, { id: "fast", value: "true" }],
});
expect(selectionFor("cursor/grok-4.6-fast", "medium")).toEqual({
modelId: "grok-4.6",
parameters: [{ id: "effort", value: "medium" }, { id: "fast", value: "true" }],
});
expect(selectionFor("cursor/grok-4.6-fast", "high")).toEqual({
modelId: "grok-4.6",
parameters: [{ id: "effort", value: "high" }, { id: "fast", value: "true" }],
});
expect(selectionFor("cursor/grok-4.6-fast", "xhigh")).toEqual({
modelId: "grok-4.6",
parameters: [{ id: "effort", value: "high" }, { id: "fast", value: "true" }],
});
});

test("kimi-k3 maps to its live effort-suffixed variants", () => {
expect(modelIdFor("cursor/kimi-k3", "low")).toBe("kimi-k3-low");
expect(modelIdFor("cursor/kimi-k3", "medium")).toBe("kimi-k3-high");
Expand Down
Loading