fix: respect explicit supportsReasoningEffort array values (#9970)

This commit is contained in:
Hannes Rudolph 2025-12-09 21:59:13 -07:00 committed by GitHub
parent f472a8298e
commit df5fdefea3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 99 additions and 4 deletions

View file

@ -87,11 +87,16 @@ export const ThinkingBudget = ({ apiConfiguration, setApiConfigurationField, mod
// "disable" turns off reasoning entirely; "none" is a valid reasoning level.
// Both display as "None" in the UI but behave differently.
// Add "disable" option if reasoning effort is not required.
// Add "disable" option only when:
// 1. requiredReasoningEffort is not true, AND
// 2. supportsReasoningEffort is boolean true (not an explicit array)
// When the model provides an explicit array, respect those exact values.
type ReasoningEffortOption = ReasoningEffortWithMinimal | "none" | "disable"
const availableOptions: ReadonlyArray<ReasoningEffortOption> = modelInfo?.requiredReasoningEffort
? (baseAvailableOptions as ReadonlyArray<ReasoningEffortOption>)
: (["disable", ...baseAvailableOptions] as ReasoningEffortOption[])
const shouldAutoAddDisable =
!modelInfo?.requiredReasoningEffort && supports === true && !baseAvailableOptions.includes("disable" as any)
const availableOptions: ReadonlyArray<ReasoningEffortOption> = shouldAutoAddDisable
? (["disable", ...baseAvailableOptions] as ReasoningEffortOption[])
: (baseAvailableOptions as ReadonlyArray<ReasoningEffortOption>)
// Default reasoning effort - use model's default if available
// GPT-5 models have "medium" as their default in the model configuration

View file

@ -18,6 +18,19 @@ vi.mock("@/components/ui", () => ({
onChange={(e) => onValueChange([parseInt(e.target.value)])}
/>
),
Select: ({ children, value, onValueChange: _onValueChange }: any) => (
<div data-testid="select" data-value={value}>
{children}
</div>
),
SelectTrigger: ({ children }: any) => <button data-testid="select-trigger">{children}</button>,
SelectValue: ({ placeholder }: any) => <span data-testid="select-value">{placeholder}</span>,
SelectContent: ({ children }: any) => <div data-testid="select-content">{children}</div>,
SelectItem: ({ children, value }: any) => (
<div data-testid={`select-item-${value}`} data-value={value}>
{children}
</div>
),
}))
vi.mock("@/components/ui/hooks/useSelectedModel", () => ({
@ -215,4 +228,81 @@ describe("ThinkingBudget", () => {
expect(setApiConfigurationField).toHaveBeenCalledWith("modelMaxTokens", 12000)
})
describe("reasoning effort dropdown", () => {
const reasoningEffortModelInfo: ModelInfo = {
supportsReasoningEffort: true,
contextWindow: 200000,
supportsPromptCache: true,
}
it("should show 'disable' option when supportsReasoningEffort is boolean true", () => {
render(<ThinkingBudget {...defaultProps} modelInfo={reasoningEffortModelInfo} />)
expect(screen.getByTestId("reasoning-effort")).toBeInTheDocument()
// "disable" should be shown when supportsReasoningEffort is true (boolean)
expect(screen.getByTestId("select-item-disable")).toBeInTheDocument()
expect(screen.getByTestId("select-item-low")).toBeInTheDocument()
expect(screen.getByTestId("select-item-medium")).toBeInTheDocument()
expect(screen.getByTestId("select-item-high")).toBeInTheDocument()
})
it("should NOT show 'disable' option when supportsReasoningEffort is an explicit array without disable", () => {
render(
<ThinkingBudget
{...defaultProps}
modelInfo={{
...reasoningEffortModelInfo,
supportsReasoningEffort: ["low", "high"],
}}
/>,
)
expect(screen.getByTestId("reasoning-effort")).toBeInTheDocument()
// "disable" should NOT be shown when model explicitly specifies only ["low", "high"]
expect(screen.queryByTestId("select-item-disable")).not.toBeInTheDocument()
expect(screen.getByTestId("select-item-low")).toBeInTheDocument()
expect(screen.queryByTestId("select-item-medium")).not.toBeInTheDocument()
expect(screen.getByTestId("select-item-high")).toBeInTheDocument()
})
it("should show 'disable' option when supportsReasoningEffort array explicitly includes disable", () => {
render(
<ThinkingBudget
{...defaultProps}
modelInfo={{
...reasoningEffortModelInfo,
supportsReasoningEffort: ["disable", "low", "high"],
}}
/>,
)
expect(screen.getByTestId("reasoning-effort")).toBeInTheDocument()
// "disable" should be shown when model explicitly includes it in the array
expect(screen.getByTestId("select-item-disable")).toBeInTheDocument()
expect(screen.getByTestId("select-item-low")).toBeInTheDocument()
expect(screen.queryByTestId("select-item-medium")).not.toBeInTheDocument()
expect(screen.getByTestId("select-item-high")).toBeInTheDocument()
})
it("should show 'none' option when supportsReasoningEffort array includes none", () => {
render(
<ThinkingBudget
{...defaultProps}
modelInfo={{
...reasoningEffortModelInfo,
supportsReasoningEffort: ["none", "low", "medium", "high"],
}}
/>,
)
expect(screen.getByTestId("reasoning-effort")).toBeInTheDocument()
// Only values from the explicit array should be shown
expect(screen.queryByTestId("select-item-disable")).not.toBeInTheDocument()
expect(screen.getByTestId("select-item-none")).toBeInTheDocument()
expect(screen.getByTestId("select-item-low")).toBeInTheDocument()
expect(screen.getByTestId("select-item-medium")).toBeInTheDocument()
expect(screen.getByTestId("select-item-high")).toBeInTheDocument()
})
})
})