diff --git a/.changeset/stupid-masks-pay.md b/.changeset/stupid-masks-pay.md
new file mode 100644
index 0000000000..021be2a11b
--- /dev/null
+++ b/.changeset/stupid-masks-pay.md
@@ -0,0 +1,5 @@
+---
+"roo-cline": patch
+---
+
+Fix jumpiness while entering API config by updating on blur instead of input
diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx
index 3ba6b245f2..3f5dd7698b 100644
--- a/webview-ui/src/components/settings/ApiOptions.tsx
+++ b/webview-ui/src/components/settings/ApiOptions.tsx
@@ -41,7 +41,6 @@ import { UnboundModelPicker } from "./UnboundModelPicker"
import { ModelInfoView } from "./ModelInfoView"
import { DROPDOWN_Z_INDEX } from "./styles"
-
interface ApiOptionsProps {
apiErrorMessage?: string
modelIdErrorMessage?: string
@@ -164,7 +163,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
value={apiConfiguration?.apiKey || ""}
style={{ width: "100%" }}
type="password"
- onInput={handleInputChange("apiKey")}
+ onBlur={handleInputChange("apiKey")}
placeholder="Enter API Key...">
Anthropic API Key
@@ -189,7 +188,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
value={apiConfiguration?.anthropicBaseUrl || ""}
style={{ width: "100%", marginTop: 3 }}
type="url"
- onInput={handleInputChange("anthropicBaseUrl")}
+ onBlur={handleInputChange("anthropicBaseUrl")}
placeholder="Default: https://api.anthropic.com"
/>
)}
@@ -218,7 +217,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
value={apiConfiguration?.glamaApiKey || ""}
style={{ width: "100%" }}
type="password"
- onInput={handleInputChange("glamaApiKey")}
+ onBlur={handleInputChange("glamaApiKey")}
placeholder="Enter API Key...">
Glama API Key
@@ -247,7 +246,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
value={apiConfiguration?.openAiNativeApiKey || ""}
style={{ width: "100%" }}
type="password"
- onInput={handleInputChange("openAiNativeApiKey")}
+ onBlur={handleInputChange("openAiNativeApiKey")}
placeholder="Enter API Key...">
OpenAI API Key
@@ -275,7 +274,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
value={apiConfiguration?.mistralApiKey || ""}
style={{ width: "100%" }}
type="password"
- onInput={handleInputChange("mistralApiKey")}
+ onBlur={handleInputChange("mistralApiKey")}
placeholder="Enter API Key...">
Mistral API Key
@@ -306,7 +305,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
value={apiConfiguration?.openRouterApiKey || ""}
style={{ width: "100%" }}
type="password"
- onInput={handleInputChange("openRouterApiKey")}
+ onBlur={handleInputChange("openRouterApiKey")}
placeholder="Enter API Key...">
OpenRouter API Key
@@ -340,7 +339,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
value={apiConfiguration?.openRouterBaseUrl || ""}
style={{ width: "100%", marginTop: 3 }}
type="url"
- onInput={handleInputChange("openRouterBaseUrl")}
+ onBlur={handleInputChange("openRouterBaseUrl")}
placeholder="Default: https://openrouter.ai/api/v1"
/>
)}
@@ -391,7 +390,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
AWS Profile Name
@@ -402,7 +401,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
value={apiConfiguration?.awsAccessKey || ""}
style={{ width: "100%" }}
type="password"
- onInput={handleInputChange("awsAccessKey")}
+ onBlur={handleInputChange("awsAccessKey")}
placeholder="Enter Access Key...">
AWS Access Key
@@ -410,7 +409,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
value={apiConfiguration?.awsSecretKey || ""}
style={{ width: "100%" }}
type="password"
- onInput={handleInputChange("awsSecretKey")}
+ onBlur={handleInputChange("awsSecretKey")}
placeholder="Enter Secret Key...">
AWS Secret Key
@@ -418,7 +417,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
value={apiConfiguration?.awsSessionToken || ""}
style={{ width: "100%" }}
type="password"
- onInput={handleInputChange("awsSessionToken")}
+ onBlur={handleInputChange("awsSessionToken")}
placeholder="Enter Session Token...">
AWS Session Token
@@ -486,7 +485,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
Google Cloud Project ID
@@ -544,7 +543,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
value={apiConfiguration?.geminiApiKey || ""}
style={{ width: "100%" }}
type="password"
- onInput={handleInputChange("geminiApiKey")}
+ onBlur={handleInputChange("geminiApiKey")}
placeholder="Enter API Key...">
Gemini API Key
@@ -572,7 +571,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
value={apiConfiguration?.openAiBaseUrl || ""}
style={{ width: "100%" }}
type="url"
- onInput={handleInputChange("openAiBaseUrl")}
+ onBlur={handleInputChange("openAiBaseUrl")}
placeholder={"Enter base URL..."}>
Base URL
@@ -580,7 +579,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
value={apiConfiguration?.openAiApiKey || ""}
style={{ width: "100%" }}
type="password"
- onInput={handleInputChange("openAiApiKey")}
+ onBlur={handleInputChange("openAiApiKey")}
placeholder="Enter API Key...">
API Key
@@ -623,7 +622,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
)}
@@ -1073,14 +1072,14 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
value={apiConfiguration?.lmStudioBaseUrl || ""}
style={{ width: "100%" }}
type="url"
- onInput={handleInputChange("lmStudioBaseUrl")}
+ onBlur={handleInputChange("lmStudioBaseUrl")}
placeholder={"Default: http://localhost:1234"}>
Base URL (optional)
Model ID
@@ -1142,7 +1141,7 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
value={apiConfiguration?.deepSeekApiKey || ""}
style={{ width: "100%" }}
type="password"
- onInput={handleInputChange("deepSeekApiKey")}
+ onBlur={handleInputChange("deepSeekApiKey")}
placeholder="Enter API Key...">
DeepSeek API Key
@@ -1232,14 +1231,14 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
value={apiConfiguration?.ollamaBaseUrl || ""}
style={{ width: "100%" }}
type="url"
- onInput={handleInputChange("ollamaBaseUrl")}
+ onBlur={handleInputChange("ollamaBaseUrl")}
placeholder={"Default: http://localhost:11434"}>
Base URL (optional)
Model ID