Skip to content

Commit 69358fb

Browse files
committed
fix(providers): correct effort resolution when modelEfforts is empty
- Change fallback in resolveUtilityTaskConfig from truthy-check to nullish coalescing - Update conflictResolver test: empty modelEfforts no longer falls back to global efforts - Add Cursor provider fixture with models lacking effort variants
1 parent 92e55ac commit 69358fb

2 files changed

Lines changed: 27 additions & 4 deletions

File tree

src/renderer/components/providers/conflictResolver.test.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
22
import { resolveConflictResolverConfig } from "./ProviderIcon";
33
import "./claude";
44
import "./codex";
5+
import "./cursor";
56
import "./gemini";
67

78
const claudeStatus = {
@@ -37,6 +38,24 @@ const codexStatus = {
3738
},
3839
};
3940

41+
const cursorStatus = {
42+
kind: "cursor",
43+
capabilities: {
44+
models: [
45+
{ id: "composer-2.5", label: "Composer 2.5" },
46+
{ id: "composer-2.5-fast", label: "Composer 2.5 Fast" },
47+
{ id: "gpt-5.5", label: "GPT-5.5" },
48+
],
49+
efforts: ["none", "low", "medium", "high", "xhigh", "max"],
50+
defaultEffort: "medium" as string | undefined,
51+
modelEfforts: {
52+
"composer-2.5": [] as string[],
53+
"composer-2.5-fast": [] as string[],
54+
"gpt-5.5": ["none", "low", "medium", "high", "xhigh"],
55+
} as Record<string, string[]>,
56+
},
57+
};
58+
4059
describe("resolveConflictResolverConfig", () => {
4160
it("falls back to registered defaults (Claude → Opus)", () => {
4261
const result = resolveConflictResolverConfig(claudeStatus, "", "");
@@ -69,9 +88,13 @@ describe("resolveConflictResolverConfig", () => {
6988
expect(result.availableEfforts).toEqual(["low", "medium", "high"]);
7089
});
7190

72-
it("falls back to global efforts when model has empty modelEfforts", () => {
73-
// haiku has modelEfforts: [] → falls back to global efforts
91+
it("does not fall back to global efforts when model has empty modelEfforts", () => {
7492
const result = resolveConflictResolverConfig(claudeStatus, "haiku", "");
75-
expect(result.availableEfforts).toEqual(["low", "medium", "high", "xHigh", "max"]);
93+
expect(result.availableEfforts).toEqual([]);
94+
});
95+
96+
it("does not show efforts for Cursor Composer models without effort variants", () => {
97+
const result = resolveConflictResolverConfig(cursorStatus, "composer-2.5", "");
98+
expect(result).toEqual({ model: "composer-2.5", effort: "", availableEfforts: [] });
7699
});
77100
});

src/renderer/components/providers/utilityTask.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ export function resolveUtilityTaskConfig(
146146
"");
147147

148148
const modelEfforts = agent.capabilities.modelEfforts[nextModel];
149-
const availableEfforts = modelEfforts?.length ? modelEfforts : [...agent.capabilities.efforts];
149+
const availableEfforts = modelEfforts ?? [...agent.capabilities.efforts];
150150
if (availableEfforts.length === 0) return { model: nextModel, effort: "", availableEfforts };
151151

152152
if (availableEfforts.includes(effort)) return { model: nextModel, effort, availableEfforts };

0 commit comments

Comments
 (0)