diff --git a/webview-ui/src/components/settings/TemperatureControl.tsx b/webview-ui/src/components/settings/TemperatureControl.tsx index b8908de536..422356bf69 100644 --- a/webview-ui/src/components/settings/TemperatureControl.tsx +++ b/webview-ui/src/components/settings/TemperatureControl.tsx @@ -9,21 +9,17 @@ interface TemperatureControlProps { export const TemperatureControl = ({ value, onChange, maxValue = 1 }: TemperatureControlProps) => { const [isCustomTemperature, setIsCustomTemperature] = useState(value !== undefined) + const [inputValue, setInputValue] = useState(value?.toString() ?? "0") // Sync internal state with prop changes when switching profiles useEffect(() => { const hasCustomTemperature = value !== undefined setIsCustomTemperature(hasCustomTemperature) + setInputValue(value?.toString() ?? "0") }, [value]) return ( -
+
{ @@ -39,31 +35,44 @@ export const TemperatureControl = ({ value, onChange, maxValue = 1 }: Temperatur

- Controls randomness in the model's responses. Higher values make output more random, lower values make - it more deterministic. + Controls randomness in the model's responses.

{isCustomTemperature && ( -
+
- { + setInputValue(e.target.value)} + onBlur={(e) => { const newValue = parseFloat(e.target.value) - onChange(isNaN(newValue) ? undefined : newValue) + if (!isNaN(newValue) && newValue >= 0 && newValue <= maxValue) { + onChange(newValue) + setInputValue(newValue.toString()) + } else { + setInputValue(value?.toString() ?? "0") // Reset to last valid value + } }} style={{ - flexGrow: 1, - accentColor: "var(--vscode-button-background)", - height: "2px", + width: "60px", + padding: "4px 8px", + border: "1px solid var(--vscode-input-border)", + background: "var(--vscode-input-background)", + color: "var(--vscode-input-foreground)", }} /> - {value?.toFixed(2)}
+

+ Higher values make output more random, lower values make it more deterministic. +

)}
diff --git a/webview-ui/src/components/settings/__tests__/TemperatureControl.test.tsx b/webview-ui/src/components/settings/__tests__/TemperatureControl.test.tsx index 8401f3d5fb..d178cfafbc 100644 --- a/webview-ui/src/components/settings/__tests__/TemperatureControl.test.tsx +++ b/webview-ui/src/components/settings/__tests__/TemperatureControl.test.tsx @@ -8,7 +8,7 @@ describe("TemperatureControl", () => { const checkbox = screen.getByRole("checkbox") expect(checkbox).not.toBeChecked() - expect(screen.queryByRole("slider")).not.toBeInTheDocument() + expect(screen.queryByRole("textbox")).not.toBeInTheDocument() }) it("renders with custom temperature enabled", () => { @@ -18,9 +18,9 @@ describe("TemperatureControl", () => { const checkbox = screen.getByRole("checkbox") expect(checkbox).toBeChecked() - const slider = screen.getByRole("slider") - expect(slider).toBeInTheDocument() - expect(slider).toHaveValue("0.7") + const input = screen.getByRole("textbox") + expect(input).toBeInTheDocument() + expect(input).toHaveValue("0.7") }) it("updates when checkbox is toggled", () => { @@ -38,12 +38,13 @@ describe("TemperatureControl", () => { expect(onChange).toHaveBeenCalledWith(0.7) }) - it("updates temperature when slider changes", () => { + it("updates temperature when input loses focus", () => { const onChange = jest.fn() render() - const slider = screen.getByRole("slider") - fireEvent.change(slider, { target: { value: "0.8" } }) + const input = screen.getByRole("textbox") + fireEvent.change(input, { target: { value: "0.8" } }) + fireEvent.blur(input) expect(onChange).toHaveBeenCalledWith(0.8) }) @@ -52,8 +53,18 @@ describe("TemperatureControl", () => { const onChange = jest.fn() render() - const slider = screen.getByRole("slider") - expect(slider).toHaveAttribute("max", "2") + const input = screen.getByRole("textbox") + + // Valid value within max + fireEvent.change(input, { target: { value: "1.8" } }) + fireEvent.blur(input) + expect(onChange).toHaveBeenCalledWith(1.8) + + // Invalid value above max + fireEvent.change(input, { target: { value: "2.5" } }) + fireEvent.blur(input) + expect(input).toHaveValue("1.5") // Should revert to original value + expect(onChange).toHaveBeenCalledTimes(1) // Should not call onChange for invalid value }) it("syncs checkbox state when value prop changes", () => {